我有一个承诺链,看起来像这样。
fistAsyncFunction()
.then(() => {
secondAsyncFunction()
})
.then(() => {
thirdAsyncFunction()
})
我注意到第三个异步函数在第二个异步函数完成之前就开始了,但是把它改成这样之后,它就按照我的要求工作了。
fistAsyncFunction()
.then(() => {
return secondAsyncFunction()
})
.then(() => {
thirdAsyncFunction()
})
似乎即使第二个异步函数没有返回任何东西,程序也在等待它返回。undefined
然后再进行下一个承诺。这是实际发生的事情吗?如果不是,那么到底发生了什么,提示javascript开始执行下一个承诺?
可以这样想
fistAsyncFunction()
.then(() => {
secondAsyncFunction()
return undefined
})
.then((iAmUndefined) => {
thirdAsyncFunction()
return undefined
})
^ 这是你的第一个使用显式返回的例子。
看起来即使第二个async函数没有返回任何东西,程序也在等待它返回undefined后再进入下一个承诺。
所以你这个算是说对了。第二个async函数没有返回任何东西,这是正确的。然而,程序并没有等待 secondAsyncFunction()
来返回未定义。而且,它不会等待 secondAsyncFunction()
完全没有。相反,你的程序在说
好吧,我知道了
secondAsyncFunction
我现在就给你打电话,让你跑了,我不会等你。相反,我只会返回undefined,然后继续前进。喂thirdAsyncFunction
!
你是正确的,在注意到你的 thirdAsyncFunction
是在你之前开始的 secondAsyncFunction
返回。
接下来,你对你的代码进行了修改,以实现你的预期行为。
fistAsyncFunction()
.then(() => {
return secondAsyncFunction()
})
.then(resultOfSecondAsyncFunction => {
thirdAsyncFunction()
return undefined
})
^ 这是你的第二个例子,有明确的回报
你的程序现在正在以你想要的方式工作,因为通过返回 secondAsyncFunction()
现在,你正在指示你的程序等待该函数的返回。
到底发生了什么,让javascript开始执行下一个承诺?
在下面,有一个特殊的函数 resolve
中的 Promise
构造函数。的时候,下一个承诺将开始执行。resolve
的函数被调用。当然,这两个承诺必须由一个 .then
.
当你有一个像这样的承诺链。
fn1().then(() => {
fn2();
}).then(() => {
fn3();
});
这就是事件的顺序:
fn1()
执行并返回一个承诺(我称之为 p1
).p1
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ .then()
方法被调用,该方法简单地存储了一个回调,并立即返回另一个许诺 p2
.p2
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ .then()
方法被调用,该方法简单地存储了一个回调,并立即返回另一个许诺 p3
不被任何东西保存或使用)。p1
解决了。 这将导致之前保存的 .then()
处理程序被调用。.then()
处理程序运行它里面的代码。 在这个特定的例子中,它调用了 fn2()
. 但是,由于 fn2()
也是异步的,它只是开始操作,然后立即返回一个承诺。 但是,在这个特殊的代码示例中,没有任何东西在看那个返回的承诺,所以没有使用它。 然后,执行从 .then()
处理程序返回到最初调用它的承诺。 该承诺查看了来自 .then()
处理器,并发现它 undefined
. 既然这里没有额外的承诺可以等待,那么就解决自己的承诺吧 p2
.p2
解决了,它就会调用它的 .then()
处理程序,它开始 fn3()
. 现在你将同时拥有 fn2()
和 fn3()
在飞行中同时进行,哪一个先完成将是不确定的(这实际上只是两个异步操作之间的竞赛)。当你改为这样做的时候。
fn1().then(() => {
return fn2();
}).then(() => {
return fn3();
});
那么,在第五步之前,一切都一样。 但是,在这个例子的第5步中,第一个 .then()
处理人 return fn2()
. 所以.., fn2()
被调用,就像前面的例子一样,它返回一个承诺,而这个承诺是从 .then()
处理程序。 这就告诉宿主承诺,它需要等到that promise也解析后再继续承诺链。
所以,如果你在一个叫做 .then()
处理程序,并且你想让承诺链等待它们,你必须返回一个从 .then()
处理程序,该处理程序链接到你的内部异步操作。 如果你不这样做,那么这些额外的异步操作只是 "fire and forget",因为没有任何东西会关注它们何时完成或是否有错误。