理解javascript承诺; 堆叠和链接

Fed*_*ico 5 javascript promise chain

我一直遇到javascript承诺的几个问题,特别是堆叠链.

谁能向我解释这些不同实现之间的差异(如果有的话)?

实施1

var serverSidePromiseChain;
serverSidePromiseChain = async().then(function(response) {
    console.log('1', response);
    return response;
}).then(function(response) {
    console.log('2', response);
    return true;
}).then(function(response) {
    console.log('3', response); // response expected to be 'true'
    return async3();
}).then(function(response) {
    console.log('4', response);
    return async4();
})
Run Code Online (Sandbox Code Playgroud)

实施2

var serverSidePromiseChain;
serverSidePromiseChain = async().then(function(response) {
    console.log('1', response);
    return response;
});

serverSidePromiseChain.then(function(response) {
    console.log('2', response);
    return true;
})
serverSidePromiseChain.then(function(response) {
    console.log('3', response); // response expected to be 'true'
    return async3();
})
serverSidePromiseChain.then(function(response) {
    console.log('4', response);
    return async4();
})
Run Code Online (Sandbox Code Playgroud)

实施3

var serverSidePromiseChain;
serverSidePromiseChain = async().then(function(response) {
    console.log('1', response);
    return response;
});

serverSidePromiseChain = serverSidePromiseChain.then(function(response) {
    console.log('2', response);
    return true;
})
serverSidePromiseChain = serverSidePromiseChain.then(function(response) {
    console.log('3', response); // response expected to be 'true'
    return async3();
})
serverSidePromiseChain = serverSidePromiseChain.then(function(response) {
    console.log('4', response);
    return async4();
})
Run Code Online (Sandbox Code Playgroud)

链的一部分返回值(步骤2中的"true")会改变行为吗?承诺是否要求所有返回的值都是异步承诺以保持行为?

jfr*_*d00 24

您正在说明链接和分支之间的不同.链接wil序列多个异步操作,因此当前一个完成时开始,你可以链接任意数量的项目,一个接一个地排序.

当一个触发操作完成时,分支将多个异步操作挂钩到所有飞行中.

实现1和3是相同的.他们被束缚住了.实现3只使用临时变量来链接,而实现1只是.then()直接使用返回值.执行没有区别.这些.then()处理程序将以串行方式调用.

实施2是不同的.它是分支的,不是链式的.因为所有后续.then()处理程序都附加到完全相同的serverSidePromiseChain承诺,所以它们都只等待第一个承诺被解析,然后所有后续的异步操作都在同一时间进行(不像其他两个选项那样连续).


理解这一点可能有助于将一个级别深入研究如何使用promises.

当你这样做(场景1和3):

p.then(...).then(...)
Run Code Online (Sandbox Code Playgroud)

会发生什么如下:

  1. 解释器获取您的p变量,在其.then()上找到方法并调用它.
  2. .then()方法只存储它传递的回调,然后返回一个新的promise对象.它此时不会调用它的回调.这个新的promise对象与原始的promise对象和它存储的回调相关联.在两者都满意之前它不会解决.
  3. 然后.then()调用新返回的promise 的第二个处理程序.同样,该.then()承诺上的处理程序只存储.then()回调,但它们尚未执行.
  4. 然后在将来的某个时候,原始的promise p将通过自己的异步操作得到解决.当它被解析后,它会调用resolve它存储的任何处理程序.其中一个处理程序将是.then()上述链中第一个处理程序的回调.如果该回调运行完成并且返回任何内容或静态值(例如,不返回promise本身),那么它将解析它在.then()第一次调用之后返回的承诺.当该承诺得到解决后,它将调用.then()上面第二个处理程序安装的解析处理程序,依此类推.

执行此操作时(方案2):

p.then();
p.then();
Run Code Online (Sandbox Code Playgroud)

p这里的一个承诺存储了来自两个.then()调用的解析处理程序.当原始承诺p得到解决时,它将调用两个.then()处理程序.如果.then()处理程序本身包含异步代码并返回promises,则这两个异步操作将同时处于飞行状态(类似行为的行为),而不是按照方案1和3中的顺序.

  • “实现 2 是不同的。它是分支的,而不是链接的。因为所有后续的 .then() 处理程序都附加到完全相同的 serverSidePromiseChain 承诺,它们都只等待第一个承诺得到解决”是(对我来说)最简洁的并明确答复。说得好。谢谢! (2认同)