gpt4 book ai didi

javascript - 链式 Q Promise 序列不起作用

转载 作者:行者123 更新时间:2023-12-02 15:31:52 24 4
gpt4 key购买 nike

在带有 Q PromiseNode.js 应用程序中,我有这段代码,我想看到这个结果:

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();
})

代码工作正常,但我不知道为什么?了解和理解这一点对我来说很重要。有人可以向我解释一下吗?

最佳答案

您所看到的是链接和分支之间的区别,它们是不同形式的 Promise 控制流。

当你这样做时:

master.then(function(){
return a();
})

然后:

master.then(function(){
console.error("end");
});

您已将两个 .then() 处理程序挂接到同一个 Promise。这是分支。当 master() 被解析时,这些 .then() 处理程序中的每一个都将被相互独立地调用,并且每个处理程序都成为自己的独立链(因此原始链是 <强>分支成两条链)。

链接就像:

master.then(function(){
return a();
}).then(function(){
console.error("end");
});

在链接情况下,直到 a() 返回的任何 Promise 也得到解析并且如果 a () 抛出或返回一个被拒绝的 Promise,这里的第二个 .then() 处理程序根本不会被调用。

在第一个示例的分支情况中,无论 是什么,都会在第一个 .then() 处理程序之后立即调用第二个 .then() 处理程序a() 返回。

当你这样做时:

master = master.then(function(){
return a();
})

在此之前:

master.then(function(){
console.error("end");
});

您正在手动链接它们,以便您有效地完成:

master.then(function(){
return a();
}).then(function(){
console.error("end");
});

请记住,每次调用 .then() 都会返回一个新的 Promise。链接,如:

a().then(b).then(c)

在链中的每个步骤创建一个新的 Promise,并且在处理程序返回的任何内容也得到解决之前,该新的 Promise 不会得到解决。

所以,当你这样做时:

master = master.then(function(){
return a();
})

你正在捕获中间的 promise (通过分配给master)并捕获它,这样你就可以将一些东西链接到它上面。如果你这样做:

master.then(function(){
return a();
})

然后,从 master.then() 返回的 Promise 就完成了,不能直接链接到上面。

<小时/>

有关链接与分支的进一步描述,请参阅这些帖子:

Understanding javascript promises; stacks and chaining

Is there a difference between promise.then.then vs promise.then; promise.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 毫秒计时器。

然后,四、五、六分支最后使用 500ms 计时器

注意:我故意这样做,这样分支计时器就不会重叠,但这不是 promise 强制执行的,因为我选择的计时器值恰好是这种情况。所有三个分支都独立运行,如果它们的事件时间重叠,则可能会交叉运行。

关于javascript - 链式 Q Promise 序列不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33248484/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com