关于async/await promise 执行顺序

发布于 2022-09-12 00:47:42 字数 732 浏览 29 评论 0

 function doA1(){  
     new Promise( function (resolve) {  
        console.log(11);  
        resolve();  
    }).then(o=>{  
       console.log(12);  
    }).then(o=>{  
       console.log(13);  
    }).then(o=>{  
       console.log(14);  
    })  
}  
  
await doA1();  
console.log(2);
//执行结果顺序为 11 12 2 13 14 
 function doA1(){
    return new Promise( function (resolve) {
        console.log(11);
        resolve();
    }).then(o=>{
       console.log(12);
    }).then(o=>{
       console.log(13);
    }).then(o=>{
       console.log(14);
    })
}

await doA1();
console.log(2);
//执行结果顺序为 11 12 13 14 2

请高手解释下为何会如此执行 特别是第一段代码 执行结果为什么不是 11 2 12 13 14

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

电影里的梦 2022-09-19 00:47:42

你好,

首先第二段代码相信不用解释了,你返回了 Promise 那么 await 就会等这个 Promise 都 resolve 了才会继续往下执行。

再看回第一段,你的问题应该主要还是在为什么 12 会在 2 之前执行,我们先把代码简化一下

new Promise(resolve => {
  console.log(11)
  resolve()
})
.then(() => console.log(12))

await Promise.resolve()

console.log(2)

按代码执行顺序,首先初始事件循环

  1. Promise 的 executor 参数是立即执行的,所以马上打印 11。
  2. 因为马上 resolve 了,后面跟着 then 故 promise 进入微事件队列中,继续执行其它平台代码。
  3. await 因为跟了一个非 Promise 的值所以会自动包上一层 Promise.resolve,即无论如何都会至少等一个微事件周期。所以得到的 undefined 也进入微事件队列。

await 阻塞了,本事件循环准备结束,开始清微事件队列

  1. 先是前面 11 得到的 promise,处理 then 回调打印 12,后面的 promise 继续入微事件队列。
  2. 接着是 await 得到 undefined,因为没有赋值,被丢弃。
  3. await 得到了值,不再阻塞,继续往下执行打印 2。
  4. await 后的平台代码执行完毕,微事件队列中还有 12 得到 promise。
  5. 重复上边过程打印 13 和 14
  6. 微事件队列已清空,本事件循环结束。
羁〃客ぐ 2022-09-19 00:47:42

await 会生成一个 Promise ,以其后表达式的值 resolve 这个 Promise(类似 Promise.resolve()),并在它的 then 回调里执行 await 返回之后的一切,同时结束程序的执行。

于是 11 是同步的,并且 resolve 立即将 Promise 置为了 fullfilled 状态。于是第一个 then 立即加入了微任务,console.log(12) 。后续所有的 then 由于它们的 promise (then 会返回一个全新的 pending Promise )处于 pending 状态不(立即)产生任何微任务。

然后,await 产生一个微任务,执行 await 之后的所有(console.log(2))。

此时,11 已经打印出来,队列里有两个微任务,console.log(12)console.log(2)

甜柠檬 2022-09-19 00:47:42

因为你没有return promise,所以await默认会将后面的值转为promise 即 实际上等效于:

 function doA1(){  
     new Promise( function (resolve) {  
        console.log(11);  
        resolve();  
    }).then(o=>{  
       console.log(12);  
    }).then(o=>{  
       console.log(13);  
    }).then(o=>{  
       console.log(14);  
    })  
}  
  
await Promise.resolve(doA1());  
console.log(2);

又:没有返回值所以await对内部的promise其实等同于没有await,故可视为以下代码:

function doA1(){  
     new Promise( function (resolve) {  
        console.log(11);  
        resolve();  
    }).then(o=>{  
       console.log(12);  
    }).then(o=>{  
       console.log(13);  
    }).then(o=>{  
       console.log(14);  
    })  
}  
doA1();
await Promise.resolve();
console.log(2);
删除会话 2022-09-19 00:47:42

目前的规范要求await必须在async中使用,且await后是一个promise才能正常执行;
这样的执行结果确实找不到答案;还是不要把时间花在这种骚操作上了:)

手心的海 2022-09-19 00:47:42

首先,由于doA1函数返回值为undefined,非Promise类型,所以,await doA1()会被转化为await Promise.reslove(doA1)
await expression表达式之后的代码,可以看做是Promisethen函数
也就是,第一段代码等同于:

Promise.resolve(doA1()).then(() => {
  console.log(2)
})

第二段代码等同于:

doA1().then(() => {
    console.log(2)
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文