夜记Promise 与 事件循环 与 await/async

之前以为自己对事件循环已经很清楚了,但万万没想到今天在地铁上看到了一个这个题,因为我从没想过await/async下的事件循环是怎样的。我主要是无法判断 async1 end 这句话应该怎么处理。

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
 
async function async2() {
  console.log('async2 start');
  return new Promise((resolve, reject) => {
    resolve();
    console.log('async2 promise');
  })
}
 
console.log('script start');
 
setTimeout(function() {
  console.log('setTimeout');
}, 0);
 
async1();
 
new Promise(function(resolve) {
  console.log('promise1');
  resolve();
}).then(function() {
  console.log('promise2');
}).then(function() {
  console.log('promise3');
});
 
console.log('script end')

没想到答案是

script start
async1 start
async2 start
async2 promise
promise1
script end
promise2
promise3
async1 end
setTimeout

看完这篇文章后,码飞_CC的这篇文章后,我理会到了这道题我为什么做错了。

总结一下就是 await 之后的代码,await为了等待后面内容的结果,先把下面的内容包装成一个微任务,在某个时间丢到微任务队列里,然后后续再执行这个函数。

但是下面代码中的第八行,前面有没有这个return,结果会很不一样。

这里结合码飞_CC的回复:

我的理解是,在async2中return的是promise,当async1中执行 await async2();语句时,进入到async2函数的执行,async2中的promise1先输出,然后promise2加入到微任务队列中(此时微任务队列【promise2】),注意,这里async1的await async2();语句此时还没执行结束(async2()函数执行还没结束,它return的是promise,因为微任务中还存在promise2,得等then执行完才算返回。但是没有return的话,async2()是默认return undefined的,所以变形1中async2()函数算执行结束了),所以async1 end此时没有入微任务队列,主线程继续执行,输出promise3,然后promise4再入微任务队列(此时微任务队列【promise2,promise4】),然后输出script end,本轮主线程执行完毕,进入事件循环,查看微任务队列,输出promise2,然后async2()函数执行结束(也就是await async2();语句结束),async1函数中await async2();语句后面的内容加入到微任务队列(此时微任务队列【promise4,async1 end】),然后后面的执行你应该知道了

我再谈谈自己的理解,首先如果await后跟的是一个非Promise内容,或者说后接的async函数没有返回一个new Promise,会直接返回undfined,然后把await的内容包裹成一个微任务丢到微任务队列,所以说如果下面的代码在没有return的情况下,进微任务队列的顺序是这样的:“promise2”、“async1 end”,“promise4”。
如果await 后面返回的是一个new Promise,顺序是这样的,先执行executor中的内容,然后通过reject把状态从unsettled转换为resolve状态,但是转换后先不干事,状态转换后的事在下一个微任务中执行,等当前的promise链中的微任务都执行完之后才把await之后的代码包装成微任务丢到微任务队列,所以微任务队列的顺序是这样的:“promise2”,“promise4”,然后等promise2执行完之后,才把“async1 end”放进微任务队列,所以先执行“promise4”,最后才执行“async1”。
但是要注意的是,我为什么要加粗那两句话,因为这句话可以解释了上面的代码中为什么async1 end在最后执行,虽然说上面的代码的Promise没有链式结构,直接resolve了,但是resolve之后的状态转换,并没有让它直接退出当前的promise,所以这里resolve可以理解为,向微任务队列中推入了一个空的微任务,就是什么都不做,等

我都晕了,看这篇把…https://segmentfault.com/q/1010000016147496


async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  //async2做出如下更改:
  return new Promise(function (resolve) {
    console.log('promise1');
    resolve();
  }).then(function () {
    console.log('promise2');
  });
}

console.log('script start');

setTimeout(function () {
  console.log('setTimeout');
}, 0)

async1();

new Promise(function (resolve) {
  console.log('promise3');
  resolve();
}).then(function () {
  console.log('promise4');
});

console.log('script end');

上述代码中第八行有没有return 语句,结果会很不一样,我不是很明白,明天再想
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值