Javascript 一行中有多个等待(嵌套异步调用)

Javascript 一行中有多个等待(嵌套异步调用),javascript,promise,async-await,Javascript,Promise,Async Await,我找不到任何关于一行中的多个等待的是什么意思或者应该如何处理的好信息。因此,我创建了以下测试代码(在节点中执行): 异步函数resolveAfterNSeconds(n,值){ 返回新承诺((解决)=>{ 设置超时(()=>{ 决心(价值); },n*1000); }); }; 异步函数测试(which){ const start=new Date().getTime(); 让结果; 开关(哪个){ 案例1: 结果=等待resolveAfterNSeconds(10,等待resolveAfte

我找不到任何关于一行中的多个
等待的
是什么意思或者应该如何处理的好信息。因此,我创建了以下测试代码(在节点中执行):

异步函数resolveAfterNSeconds(n,值){
返回新承诺((解决)=>{
设置超时(()=>{
决心(价值);
},n*1000);
});
};
异步函数测试(which){
const start=new Date().getTime();
让结果;
开关(哪个){
案例1:
结果=等待resolveAfterNSeconds(10,等待resolveAfterNSeconds(2,‘完成’));
打破
案例2:
结果=等待resolveAfterNSeconds(2,等待resolveAfterNSeconds(10,‘完成’));
打破
案例3:
结果=等待resolveAfterNSeconds(10,resolveAfterNSeconds(2,‘完成’));
打破
案例4:
结果=等待resolveAfterNSeconds(2,resolveAfterNSeconds(10,‘完成’));
打破
案例5:
结果=resolveAfterNSeconds(10,等待resolveAfterNSeconds(2,‘完成’));
打破
案例6:
结果=resolveAfterNSeconds(2,等待resolveAfterNSeconds(10,‘完成’));
打破
}
const end=new Date().getTime();
log([which,result,(new Date().getTime()-start)/1000]);
}
测试(1);//[1,‘完成’,12],如预期
测试(2);//[2,‘完成’,12],如预期
测试(3);//[3,‘完成’,10],如预期(某种程度上)
测试(4);//[4,‘完成’,10],但预期:[4,承诺,2]
测试(5);//[5,承诺,2],正如预期的那样
测试(6);//[6,承诺,10],正如预期的那样
我想我确实理解为什么在案例3中,返回的是“done”而不是相应的Promise-此时2s超时已经完成(对吗?)

不,与案例4相同

然而,我不理解案例4:似乎一开始等待的人也与内在承诺有某种联系,因为否则,这个承诺不应该在2秒后返回(而不是“完成”)吗

如果您用另一个承诺(Y)来解析一个承诺(X),那么承诺X采用承诺Y的状态

但是,如果外部等待事实上也与内部承诺相关,这难道不意味着案例1和案例2是无意义的,应该总是用案例3和案例4(分别)代替吗

不,他们有不同的行为

如果
等待
一个承诺(Y),并将其解析值用作创建另一个承诺(X)的函数的参数,则该函数在解析Y之前不会开始运行

如果您不等待它,那么它将在
Y
解析之前开始运行(因此封装在承诺中的两个操作可以并行运行)

我想我确实理解为什么在案例3中,返回的是“done”而不是相应的Promise-此时2s超时已经完成(对吗?)

不,与案例4相同

然而,我不理解案例4:似乎一开始等待的人也与内在承诺有某种联系,因为否则,这个承诺不应该在2秒后返回(而不是“完成”)吗

如果您用另一个承诺(Y)来解析一个承诺(X),那么承诺X采用承诺Y的状态

但是,如果外部等待事实上也与内部承诺相关,这难道不意味着案例1和案例2是无意义的,应该总是用案例3和案例4(分别)代替吗

不,他们有不同的行为

如果
等待
一个承诺(Y),并将其解析值用作创建另一个承诺(X)的函数的参数,则该函数在解析Y之前不会开始运行


如果您不等待它,那么它将在
Y
解决之前开始运行(因此,封装在承诺中的两个操作可以并行运行)。

基本上,
async/await
只是
Promise
的包装。如果调用任何
async
函数,它将返回Promise,并使用
wait
调用它,将停止主上下文的执行,并等待
Promise
完成。但是,如果您在不使用wait
的情况下调用它,那么它将只是一个简单的函数调用,承诺将开始执行,但不会等待它的结束,其余代码将同步执行

因此,在案例4中,使用
await
调用
resolveAfterNSeconds
resolveAfterNSeconds(2,值)
和调用
resolveAfterNSeconds(10,值)
参数中的
resolveAfterNSeconds(10,值)
同步执行
resolveAfterNSeconds(10,值)
,导致将内部
Promise
作为第二个参数传递的原因

因此,
等待resolveAfterNSeconds(2,value)
停止主上下文的执行,并且将在内部创建
承诺
链,因此只有当整个
承诺
链将被解析,并且
承诺
链的结果是
完成
最后解析的值时,执行才会继续,这就是
结果
变量


这就是为什么你得到了
完成
价值

基本上,
async/await
只是
Promise
的包装。如果调用任何
async
函数,它将返回Promise,并使用
wait
调用它,将停止主上下文的执行,并等待
Promise
完成。但是,如果您在不使用wait
的情况下调用它,那么它将只是一个简单的函数调用,承诺将开始执行,但不会等待它的结束,其余代码将同步执行

因此,在案例4中,使用
await
调用
resolveAfterNSeconds
resolveAfterNSeconds(2,值)
和调用
resolveAfterNSeconds(10,值)
参数中的
resolveAfterNSeconds(10,值)
同步执行
resolveAfterNSeconds(10,值)
,什么导致将内部
承诺作为第二个传递