ES8 async/await复习

近期复习async/await语法,发现await的暂停异步函数执行机制很有趣

发生这种情况时十分微妙,最慢的竟然比最快的还要快?

async function test() {
        let a = new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('最慢的','inner');
                resolve('最慢的');
            }, 3000);
        });
        let b = new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log('中等的','inner');
                resolve('中等的');
            }, 2000);
        });

        console.log(await a);
        await Promise.resolve(setTimeout(() => console.log('最快的'), 1000));
        console.log(await b);
        console.log('end');
    }
//输出结果:
//中等的 inner
//最慢的 inner
//最慢的
//中等的
//end
//最快的

关键在于await暂停的是异步函数代码的执行,看一下await的用法:

[返回值] = await [表达式]

返回值:

返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身(被当做已解决的期约)。

表达式:

一个 Promise 对象或者任何要等待的值。

另外参考红书的一句话


回到代码中:

//执行中的异步期约,3秒后输出“最慢的”
console.log(await a);
//一个未执行的异步期约,1秒后输出“最快的”
await Promise.resolve(setTimeout(() => console.log('1'), 1000));
//执行中的异步期约,2秒后输出“中等的”
console.log(await b);
//同步代码
console.log('end');

理清一下代码的执行顺序:

  1. 等待a求值
  2. 等待Promise.resolve(setTimeout(() => console.log('1'), 1000))的求值
  3. 等待b的求值

进入代码后,期约a与b在第一时间就声明并且异步求值

a在3秒后解决,返回“最慢的”,解决前打印“最慢的 inner”

b在2秒后解决,返回“中等的”,解决前打印“中等的 inner”

此时碰到第一个await

js会等待a的求值,但别忘了上面引用红书说过await会暂停代码的执行,但函数的其余部分仍然会进行异步求值,b的求值也在异步进行中。

所以b理所应当的最先解决,并且打印了“中等的 inner”

随后,a解决,打印了“中等的 inner”

此时,a返回了“最慢的”,得以打印“最慢的”

到了第二个await了

await会怎么处理Promise.resolve(...)?

Promise.resolve(...)是一个已解决期约的初始化(同步代码),此时因为前面await在等待一个期约的解决,这个初始化被暂停了。

js运行至此,初始化了已解决期约,求得的值是定时器

setTimeout(() => console.log('1'), 1000)的id(因为他是第三个定时器所以是3)

Promise.resolve(...)成功被初始化,作为已解决期约,await能够直接求得它的值,完全不用等待

但是它的值是个定时器,并且期约被初始化后定时器才开始运行,1秒后输出“最快的”。

到了第三个await

如上文所说,期约b早已解决,await 直接求得了他的值“中等的”并直接打印

至此,await全部执行完成。

剩下的代码的还有

同步代码:console.log('end')

异步任务中的:定时器打印“最快的”

所以最终输出的顺序是

中等的 inner
最慢的 inner
最慢的
中等的
end
最快的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值