在Promise.prototype.then

时间:2018-12-19 16:06:43

标签: javascript promise

我最近发现您可以通过一个承诺,而不是onFulfilled中的promise.then函数

例如:

var p = new Promise(function(resolve, reject) {
    setTimeout(function(){
        resolve("First Promise");
    }, 4000);
});

var q = new Promise(function(resolve, reject) {
    setTimeout(function(){
        console.log("Yo");
        resolve("Second Promise");
    }, 8000);
});


p.then(q).then(function(data){
    console.log(data);
});

这将打印以下输出

First Promise (at 4th second)
Yo (at 8th second)

这听起来很奇怪,因为实际上,我们仅在promise.then中传递函数,而不传递新的Promise。

有人可以帮助我某些用例吗?而且,如果您在promise.then内通过承诺,那么确切的行为是什么?

编辑:

我在Spotify Web Player上看到了类似的行为。 enter image description here

this._onStreamerConnect()返回一个Promise,其上附加有.then.then的参数e也是Promise,如右侧面板中的“观看”标签所示

2 个答案:

答案 0 :(得分:2)

根据MDN documentation

  

如果省略了一个或两个自变量,或者为它们提供了非函数,则then将缺少处理程序,但不会产生任何错误。如果调用Promise的{​​{1}}采用then没有处理程序的状态(fulfillmentrejection),则新的then无需其他处理程序即可创建,只需采用调用了Promise的原始Promise的最终状态即可。

这意味着调用then与调用p.then(q).then(function...)相同。 p.then(function...)参数将被完全忽略,而不是Promise链的一部分。

q的执行程序函数最终在8秒内解析,而与q无关,后者仍在4秒内解析,并且您不会从输出中看到字符串p的消耗。

答案 1 :(得分:1)

要添加到Patrick Roberts's correct answer,您可以then返回承诺,然后then函数将等待Promise,然后继续< / em>。但是,为此,您需要将函数传递给then并返回一个Promise。

这样,如果您的行看起来像这样:

p.then(() => q).then(function(data){
    console.log(data);
});

或者没有lambda:

p.then(function() { return q; }).then(function(data){
    console.log(data);
});

然后您将看到输出:

First Promise (at 4th second)
Yo (at 8th second)
Second Promise (at 8th second)

编辑:关于Spotify,对您正在查看的_runOnDevice函数的大多数调用具有明确绑定的函数作为第二和第三个参数。

尽管它们的位置相同,但大多数参数名称都相同(ten),这使得后面的用法有些混乱。我猜想这些都是使用lambda大量转译的async函数。

正如Patrick在评论中指出的那样,对_runOnDevice的至少一个调用似乎将Promise作为第二个参数。对我来说,这似乎是个错误。

Spotify code: vendor.125e9736.js