我一直试图理解javscript中的promise调用背后的架构,这是我认为正在幕后发生的事情
function Promise() {
this.stack = [];
this.then = function(fn) {
this.stack.push(fn);
return this;
}
this.resolve = function(data) {
if (this.stack.length) {
var cb = this.stack[0];
this.stack.shift();
cb.call(null, {
resolve: this.resolve.bind(this)
}, data);
}
}
}
// --- below is a working implementation --- //
var bar = function() {
var promise = new Promise();
setTimeout(function() {
console.log("1");
promise.resolve();
}, 2000);
return promise;
}
bar().then(function(p) {
setTimeout(function() {
console.log("2");
p.resolve();
}, 1000);
}).then(function(p) {
setTimeout(function() {
console.log("3");
p.resolve();
}, 500);
}).then(function(p) {
setTimeout(function() {
console.log("4");
p.resolve();
}, 300);
});
在我的库中,每次resolve
调用之后,我正在调用堆栈中的下一个回调并将数组移位一个
但是在我链接的其他库中,每当第一个承诺被解决时,就会在遍历整个数组的同时循环运行,同时不断调用回调堆栈。
function execCallbacks() {
/*jshint bitwise:false*/
if (status === 0) {
return;
}
var cbs = pendings,
i = 0,
l = cbs.length,
cbIndex = ~status ? 0 : 1,
cb;
pendings = [];
for (; i < l; i++) {
(cb = cbs[i][cbIndex]) && cb(value);
}
}
_complete: function(which, arg) {
// switch over to sync then()
this.then = which === 'resolve' ?
function(resolve, reject) {
resolve && resolve(arg);
} :
function(resolve, reject) {
reject && reject(arg);
};
// disallow multiple calls to resolve or reject
this.resolve = this.reject =
function() {
throw new Error('Promise already completed.');
};
// complete all waiting (async) then()s
var aThen, i = 0;
while (aThen = this._thens[i++]) {
aThen[which] && aThen[which](arg);
}
delete this._thens;
}
function complete(type, result) {
promise.then = type === 'reject' ?
function(resolve, reject) {
reject(result);
} :
function(resolve) {
resolve(result);
};
promise.resolve = promise.reject = function() {
throw new Error("Promise already completed");
};
var i = 0,
cb;
while (cb = callbacks[i++]) {
cb[type] && cb[type](result);
}
callbacks = null;
}
我想理解,为什么在数组中循环运行以处理链接到resolve的下一个函数! 我在建筑中缺少什么?
答案 0 :(得分:1)
在我的库中,每次
resolve
调用之后,我正在调用堆栈中的下一个回调并将数组移位一个
这是一个回调队列,不是承诺。一个承诺只能解决一次。制作承诺.then()
链时,它只是创建多个承诺对象,每个对象代表一步之后的异步结果。