ES8 async/await复习

近期复习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版权协议,转载请附上原文出处链接和本声明。