我正在尝试编写自己的Promises / A +兼容承诺实现。
以下是第二次(不完整)尝试。
当我进一步开发它时,这看起来像是一个继续可行的实现吗?
const uninitializedToPending = p=>{
p['__status__'] = 'pending';
p['__isResolved__'] = false;
}
const pendingToFulfilled = (p,result)=>{
p['__status__'] = 'fulfilled';
p['__isResolved__'] = true;
p['__result__'] = result;
}
const pendingToRejected = (p,reason)=>{
p['__status__'] = 'rejected';
p['__isResolved__'] = true;
p['__result__'] = reason;
}
const go = async(function(thens, result) {
while (thens.length) {
thens.pop()(result);
}
});
function async(cb) {
return (...args)=>setTimeout(()=>cb(...args));
}
var id = 0;
function Promise(executor=()=>{}) {
const thens = []
, catches = [];
const p = {
id: ++id,
then,
catch: ccatch,
resolve,
reject,
};
uninitializedToPending(p);
executor(resolve, reject);
return p;
function resolve(result) {
pendingToFulfilled(p, result);
go(thens, result);
}
function reject(reason) {
pendingToRejected(p, reason);
go(catches, reason);
}
function then(cb) {
const p2 = new Promise();
thens.unshift(result=>{
const result2 = cb(result);
if (result2 && result2.then) {
p2['__isResolved__'] = true;
result2.then((result)=>{
p2.resolve(result);
return result;
}
);
return;
}
p2.resolve(result2)
}
);
return p2;
}
function ccatch(cb) {
const p2 = new Promise();
catches.unshift(reason=>{
cb(reason);
p2.reject(reason);
}
);
return p2;
}
}
// "Tests"
const p = new Promise(() => {}); // unresolved, pending
const q = new Promise(resolve => resolve('foo')); // resolved, fulfilled, value: foo
const r = new Promise((_,reject) => reject('foo')); // resolved, rejected, reason: foo
const s = new Promise(resolve => resolve('foo')).then(result => result + ' foo'); // resolved, fulfilled, value: "foo foo"
const t = new Promise(resolve => resolve('foo')).then(result => result + ' foo').then(result => result + ' foo'); // resolved, fulfilled, value: "foo foo foo"
const u = new Promise(resolve => resolve('foo')).then(result => new Promise(resolve => resolve(result + ' foo'))); // resolved, fulfilled, value: "foo foo"
const v = new Promise(resolve => resolve('foo')).then(result => new Promise(resolve => resolve(result + ' foo')).then(result => result + ' foo')); // resolved, fulfilled, value: "foo foo foo"
const w = new Promise(resolve=>resolve('foo'));
// branching:
w.then(result=>'a').then(console.log);
w.then(result=>'b').then(console.log);