事件循环与 async/await

前提:

  1. 了解什么是同步任务,什么是异步任务,以及宏任务和微任务
  2. 了解了事件循环的基本原理
  3. 参考:JS 事件循环 同步任务 + 异步任务(宏任务 + 微任务)
async function fn1() {
	console.log(2)
	await fn2()
	console.log(6)
}

async function fn2() {
	new Promise(resolve => {
		console.log(3)
		resolve(5)
	}).then(res => {
		console.log(res)
	}).then(() => {
		console.log(7)
	})
}
console.log(1)
fn1()
console.log(4)

不卖关子,输出答案是
1 2 3 4 5 6 7
解释:

  1. 首先输出1;
  2. 执行 fn1,输出2;
  3. 开始执行 fn2,输出3,并 resolve(5)fn2、fn1 中的第一层代码中不再出现同步代码,于是我们的视线跳出这2个函数,找到了console.log(4),输出4;
  4. 回到 resolve(5),这里执行了 resolve,于是看到后面的第一个 then,是微任务,暂不执行,放入微任务队列(queue == [console.log(res)]);
  5. 然后看到第二个 then,由于第一个 then 中的代码没有执行(处于微任务队列中),所以第二个 then 中的代码我们暂不关心(具体原因后面会说);
  6. fn2 中的代码执行结束(尽管还有事件未被执行或放入队列),因为整个 fn2 中没有任何 return,于是 await 得到了一个 Promise.resolve(undefined),并且包裹了 console.log(6),代码可以这样理解:
await fn2()
console.log(6)
// 等价于
Promise.resolve(undefined).then(() => {
	console.log(6)
})
  1. 所以我们相当于看到了一个微任务,将其放入微任务队列
    queue == [then(() => console.log(res)).then(() => console.log(7)), then(() => console.log(6))]);
  2. 然后我们发现没有任何其他任务了,于是开始执行微任务队列中的事件,取出并执行console.log(res) ,输出 5;
  3. 执行到这里的时候,第一个 then 内自动执行了一个 Promise.resolve(undefined),将 undefined传给了第二个 then,并将第二个then 放入微任务队列(queue == [then(() => console.log(6)), then((undefined) => console.log(7))]),然后这里的两个任务按照队列顺序执行即可,输出6,7。
    整个输出结束。

如果我们这样书写,会更好理解:

async function fn1() {
	console.log(2)
	await fn2()
	console.log(6)
}

async function fn2() {
	new Promise(resolve => {
		console.log(3)
		resolve(5)
	}).then(res => {
		console.log(res)
		return Promise.resolve(undefined)
	}).then(() => {
		console.log(7)
	})
}
console.log(1)
fn1()
console.log(4)

输出: 1 2 3 4 5 6 7

当我们这样写时,就会更明显:

async function fn1() {
	console.log(2)
	await fn2()
	console.log(6)
}

async function fn2() {
	new Promise(resolve => {
		console.log(3)
		resolve(5)
	}).then(res => {
		console.log(res)
		return new Promise(resolve1 => {
			resolve1(7)
		})
	}).then((res1) => {
		console.log(res1) // 7
	})
}
console.log(1)
fn1()
console.log(4)

输出:1 2 3 4 5 6 7

单独讨论一下第一个 then

...
}).then(res => {
	console.log(res)
	// 省略了一句 retuen Promise.resolve(undefined)
	// 当我们不给后方的 then 传递 Promise 时,
	// 会自动传递一个 Promise.resolve(undefined)
}).then((res1) => {
	console.log(res1) // 7
})
...
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值