近期复习async/await语法,发现await的暂停异步函数执行机制很有趣
发生这种情况时十分微妙
async function test() {
let a = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('最慢的');
resolve();
}, 3000);
});
let b = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('中等的');
resolve();
}, 2000);
});
await a;
await Promise.resolve(setTimeout(() => console.log('最快的'), 1000));
await b;
console.log('end');
}
//中等的
//最慢的
//end
//最快的
关键在于await暂停的是异步函数代码的执行
来看一下await的用法:
[返回值] = await [表达式]
表达式
一个 Promise 对象或者任何要等待的值。
返回值
返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身(被当做已解决的期约)。
另外参考红书的一句话
回到代码中
await a;//执行中 的异步期约 3秒后输出 最慢的
await Promise.resolve(setTimeout(() => console.log('1'), 1000));
//一个 未执行 的异步期约 1秒后输出 最快的
await b;//执行中 的异步期约 2秒后输出中等的
console.log('end');
await会暂停代码的执行,但微任务仍然会进行异步求值
正在被异步求值的代码就是a与b
关键是await会怎么处理Promise.resolve(...)
Promise.resolve(...)是一个已解决期约的初始化(同步代码),此时因为前面await在等待一个期约的解决,这个初始化被暂停了。
回来看异步代码,明显b先求值完成,那么b先输出“中等的”
再到a,输出“最慢的”
此时异步函数终于恢复执行了!
Promise.resolve(...)成功被初始化,作为已解决期约,await能够直接求得它的值,完全不用等待!故异步代码也不会被暂停,来看求得的值
setTimeout(() => console.log('1'), 1000)
此时里面的定时器开始工作
再来看看console.log('end')
这个完全不是期约,是同步代码
这个时候:
同步执行的是console.log('end')
异步执行的是console.log('1')
所以:
2
3
end
1
十分有趣
版权声明:本文为qq_19433031原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。