链式 Q Promise 序列不起作用
Chained Q Promise sequence wont work
在 Node.js
应用 Q
Promise
中,我有这段代码,我想看到这个结果:
a
b
end
但我看到了这个:
end
a
b
这是我的代码:
var a = function(){
return q.Promise(function(resolve, reject){
resolve("a");
});
};
var b = function(){
return q.Promise(function(resolve, reject){
resolve("b");
});
};
var c = function(){
return q.Promise(function(resolve, reject){
resolve("c");
});
};
var master = q();
master.then(function(){
return a();
})
.then(function(res){
console.error(res);
return b();
})
.then(function(res){
console.error(res);
return c();
});
master.then(function(){
console.error("end");
});
如果我更改此部分:
master.then(function(){
return a();
})
对此:
master = master.then(function(){
return a();
})
代码工作正常,但我不知道为什么?了解和理解这一点对我来说很重要。有人可以给我解释一下吗?
您看到的是链接和分支之间的区别,它们是承诺控制流的不同形式。
当你这样做时:
master.then(function(){
return a();
})
然后,然后:
master.then(function(){
console.error("end");
});
您已将两个 .then()
处理程序挂接到同一个承诺。这是分支。当 master()
被解析时,这些 .then()
处理程序中的每一个都将彼此独立地调用,并且每个都成为自己的独立链(因此原始链被 分支 为两条链)。
链接就像:
master.then(function(){
return a();
}).then(function(){
console.error("end");
});
在链接的情况下,第二个 .then()
处理程序将不会被调用,直到 a()
返回的任何承诺也被解决并且如果 a()
抛出或 returns a拒绝承诺这里的第二个 .then()
处理程序根本不会被调用。
在第一个示例的分支情况下,第二个 .then()
处理程序在第一个 .then()
处理程序之后立即被调用,而不管 a()
returns.
当你这样做时:
master = master.then(function(){
return a();
})
在你做之前:
master.then(function(){
console.error("end");
});
您正在手动链接它们,以便有效地完成:
master.then(function(){
return a();
}).then(function(){
console.error("end");
});
请记住,每次调用 .then()
returns 都是一个新的承诺。链接,如:
a().then(b).then(c)
在链中的每个步骤创建一个新的新承诺,并且在处理程序 returns 也被解决之前,新的承诺不会被解决。
所以,当你在做的时候:
master = master.then(function(){
return a();
})
您正在抓住那个中间承诺(通过分配给 master
)并坚持下去,这样您就可以将一些东西链接到它上面。如果你这样做:
master.then(function(){
return a();
})
然后,从 master.then()
返回的承诺已经完成,不能直接链接到。
有关链接与分支的进一步描述,请参阅这些帖子:
这是一个显示 promise 分支的片段:
function log(str) {
var d = document.createElement("div");
d.textContent = str;
document.body.appendChild(d);
}
function setDelay(t, msg) {
return function() {
return delay(t, msg);
}
}
function delay(t, msg) {
// if only one string argument, default t to 500ms
if (typeof t === "string" && typeof msg === "undefined") {
msg = t;
t = 500;
}
return new Promise(function(resolve) {
setTimeout(function() {
log(msg);
resolve(msg);
}, t);
});
}
var x = Promise.resolve().then(setDelay("One"))
.then(setDelay("Two"))
.then(function() {
log("Three");
});
x.then(setDelay(500, "Four"))
.then(setDelay(500, "Five"))
.then(setDelay(500, "Six"));
x.then(setDelay(50, "Seven"))
.then(setDelay(50, "Eight"))
.then(setDelay(50, "Nine"));
x.then(setDelay(10, "Ten"))
.then(setDelay(10, "Eleven"));
说明
一、二、三链接在一起,所有分支都依赖于它们。然后,这条链分裂成三个独立的分支。
十、十一分支首先执行,因为它有 10 毫秒计时器。
然后,接下来是七、八、九分支,定时器为 50 毫秒。
然后,四、五、六分支以 500 毫秒计时器结束
注意:我故意这样做是为了让分支计时器不重叠,但这不是承诺强制执行的事情,由于我选择的计时器值,这里恰好是这种情况。所有三个分支都是 运行 独立的,如果它们的活动时间重叠,则可以交错。
在 Node.js
应用 Q
Promise
中,我有这段代码,我想看到这个结果:
a
b
end
但我看到了这个:
end
a
b
这是我的代码:
var a = function(){
return q.Promise(function(resolve, reject){
resolve("a");
});
};
var b = function(){
return q.Promise(function(resolve, reject){
resolve("b");
});
};
var c = function(){
return q.Promise(function(resolve, reject){
resolve("c");
});
};
var master = q();
master.then(function(){
return a();
})
.then(function(res){
console.error(res);
return b();
})
.then(function(res){
console.error(res);
return c();
});
master.then(function(){
console.error("end");
});
如果我更改此部分:
master.then(function(){
return a();
})
对此:
master = master.then(function(){
return a();
})
代码工作正常,但我不知道为什么?了解和理解这一点对我来说很重要。有人可以给我解释一下吗?
您看到的是链接和分支之间的区别,它们是承诺控制流的不同形式。
当你这样做时:
master.then(function(){
return a();
})
然后,然后:
master.then(function(){
console.error("end");
});
您已将两个 .then()
处理程序挂接到同一个承诺。这是分支。当 master()
被解析时,这些 .then()
处理程序中的每一个都将彼此独立地调用,并且每个都成为自己的独立链(因此原始链被 分支 为两条链)。
链接就像:
master.then(function(){
return a();
}).then(function(){
console.error("end");
});
在链接的情况下,第二个 .then()
处理程序将不会被调用,直到 a()
返回的任何承诺也被解决并且如果 a()
抛出或 returns a拒绝承诺这里的第二个 .then()
处理程序根本不会被调用。
在第一个示例的分支情况下,第二个 .then()
处理程序在第一个 .then()
处理程序之后立即被调用,而不管 a()
returns.
当你这样做时:
master = master.then(function(){
return a();
})
在你做之前:
master.then(function(){
console.error("end");
});
您正在手动链接它们,以便有效地完成:
master.then(function(){
return a();
}).then(function(){
console.error("end");
});
请记住,每次调用 .then()
returns 都是一个新的承诺。链接,如:
a().then(b).then(c)
在链中的每个步骤创建一个新的新承诺,并且在处理程序 returns 也被解决之前,新的承诺不会被解决。
所以,当你在做的时候:
master = master.then(function(){
return a();
})
您正在抓住那个中间承诺(通过分配给 master
)并坚持下去,这样您就可以将一些东西链接到它上面。如果你这样做:
master.then(function(){
return a();
})
然后,从 master.then()
返回的承诺已经完成,不能直接链接到。
有关链接与分支的进一步描述,请参阅这些帖子:
这是一个显示 promise 分支的片段:
function log(str) {
var d = document.createElement("div");
d.textContent = str;
document.body.appendChild(d);
}
function setDelay(t, msg) {
return function() {
return delay(t, msg);
}
}
function delay(t, msg) {
// if only one string argument, default t to 500ms
if (typeof t === "string" && typeof msg === "undefined") {
msg = t;
t = 500;
}
return new Promise(function(resolve) {
setTimeout(function() {
log(msg);
resolve(msg);
}, t);
});
}
var x = Promise.resolve().then(setDelay("One"))
.then(setDelay("Two"))
.then(function() {
log("Three");
});
x.then(setDelay(500, "Four"))
.then(setDelay(500, "Five"))
.then(setDelay(500, "Six"));
x.then(setDelay(50, "Seven"))
.then(setDelay(50, "Eight"))
.then(setDelay(50, "Nine"));
x.then(setDelay(10, "Ten"))
.then(setDelay(10, "Eleven"));
说明
一、二、三链接在一起,所有分支都依赖于它们。然后,这条链分裂成三个独立的分支。
十、十一分支首先执行,因为它有 10 毫秒计时器。
然后,接下来是七、八、九分支,定时器为 50 毫秒。
然后,四、五、六分支以 500 毫秒计时器结束
注意:我故意这样做是为了让分支计时器不重叠,但这不是承诺强制执行的事情,由于我选择的计时器值,这里恰好是这种情况。所有三个分支都是 运行 独立的,如果它们的活动时间重叠,则可以交错。