Javascript 承诺#所有与顺序等待-时间分辨率差异

Javascript 承诺#所有与顺序等待-时间分辨率差异,javascript,time,promise,async-await,Javascript,Time,Promise,Async Await,在下面的代码片段中,使用promise#all并按顺序等待每个promise时,解析时间是不同的。我想深入了解发生了什么,因为这似乎是处理性能时的一个警告 *编辑:添加了另一个没有函数调用的情况,可能我缺少了Wait的工作方式 //代码在这里 window.onload=函数(){ 设p=新承诺((res,rej)=>{ 设置超时(()=>{ res('p OK') }, 5000); }) 让p2=新承诺((res,rej)=>{ 设置超时(()=>{ res('p2ok') }, 5000

在下面的代码片段中,使用promise#all并按顺序等待每个promise时,解析时间是不同的。我想深入了解发生了什么,因为这似乎是处理性能时的一个警告

*编辑:添加了另一个没有函数调用的情况,可能我缺少了Wait的工作方式

//代码在这里
window.onload=函数(){
设p=新承诺((res,rej)=>{
设置超时(()=>{
res('p OK')
}, 5000);
})
让p2=新承诺((res,rej)=>{
设置超时(()=>{
res('p2ok')
}, 5000);
})
让p3=新承诺((res,rej)=>{
设置超时(()=>{
res(p3正常)
}, 5000);
})
异步函数pp(){
返回新承诺((res,rej)=>{
设置超时(()=>{
res(“pp OK”);
}, 5000);
});
}
异步函数a(){
释放=等待承诺;
返回`#a${out}`;
}
异步函数b(){
放出1=等待p;
let out 2=等待pp();
返回`#b${out1}${out2}`;
}
异步函数c(){
放出1=等待p;
放出2=等待p2;
放出3=等待p3;
返回`#c${out1}${out2}${out3}`;
}
let out1=document.getElementById(“out1”);
let out2=document.getElementById(“out2”);
let out32=document.getElementById(“out2”);
const date=new date().getSeconds();
然后(()=>out1.innerHTML+=`在${new Date().getSeconds()-Date}s`之后完成);
然后(()=>out2.innerHTML+=`在${new Date().getSeconds()-Date}s`之后完成);
然后(()=>out3.innerHTML+=`在${new Date().getSeconds()-Date}s`之后完成);
}

保证

顺序等待

顺序等待而不执行fnc


在第一个函数中,它立即执行
pp
以启动承诺超时。 在第二个函数中,它等待
p
完成,然后执行
pp
以启动承诺超时

等待
关键字“blocks*”执行,直到承诺解决,然后继续下一行

回复:更新

在您的第三个示例中,所有承诺都是从时间开始的。
wait
关键字等待承诺得到解决。因为你所有的承诺都是同时开始的,它们都会在一个很小的三角洲内解决。当您点击
等待p2
时,它可能已经解决了。同样适用于
p3

在第二个示例中,
pp
直到
p
完成才开始


[*]它并不会真正阻止执行,但这就是它对代码的影响。

一些要点可能会澄清一些问题:

  • 传递给
    newpromise
    的构造函数回调函数将立即执行,这意味着
    setTimeout
    延迟将在此时生效,无论您是否等待它

  • 因此,由
    p
    p2
    p3
    创建的超时都会在初始化这些变量后立即启动。由于它们都将在5秒后超时,因此相应的承诺(
    p
    p2
    p3
    )将大约同时得到解决。同样,这与您是否使用
    等待
    然后
    承诺无关。全部
    ,或者干脆忘记这些承诺,不做任何事情

  • 相反,函数
    pp
    只是一个函数。这不是承诺。只有当您实际调用该函数时,您才能创建一个承诺,该承诺具有相应的启动超时

  • wait
    使
    async
    函数立即返回,返回一个承诺。这意味着函数的其余代码将被延迟,但其他Javascript代码的其余代码将被延迟:函数将返回,并在该函数调用后继续执行。当调用堆栈为空时,将处理不同的事件队列。所以它不是阻塞。一旦传递给
    await
    的承诺得到解决,就会神奇地发生一些事情:恢复
    async
    的函数执行上下文,并继续执行,直到下一个
    await
    。如果没有更多的
    await
    执行,并且函数结束,那么它返回的承诺(当它遇到第一个
    await
    时)将得到解决

  • 承诺。所有
    不影响个人承诺的解决时间。它创建了一个新的承诺,当所有给定的承诺都已解决时,该承诺就会解决。如上所述,您案例中的承诺(
    p
    p2
    )大约在同一时刻解决,因此
    承诺。所有的承诺也将在大约5秒钟后解决

  • 如果您确实
    等待pp()
    ,您只会在那里创建承诺,而不是更早。由于前面有一个
    wait p
    ,执行
    pp()
    需要5秒钟。因此,直到第二次执行
    wait
    ,相应的超时才会开始。这就是为什么
    等待p;等待pp()
    需要两次5秒才能解决

  • 当你等待p时,情况就不同了;等待p2。在那里,两个承诺都已经创建,它们的超时已经开始。因此,当5秒钟后第一个
    await
    结束时,JS将到达第二个
    await