关于async以及await的困惑

await与async

从名称上来说的话,async是“异步”,用来声明一个function是异步的,而await用于等待一个异步方法执行完成。

并且根据语法,await只能出现在async函数中。

async

通过下面的代码:

<script type="text/javaScript">
    async function test(){ return 'hello world'; } let i=test(); console.log('测试的值:', i)
</script>

得出:

image-20201127170159491

它的原型竟然是Peomise对象。async函数会返回一个Promise对象,并且,如果在函数中return一个直接量,async会把这个直接量通过Promise.resovle()封装成Promise对象。

由于Promise具有无等待的特点,所有在没有await的情况下执行async,他会立即执行,返回一个Promise对象,不会阻塞后面语句的执行。

await

<script>
    function test1() {
        return "hello1";
    }
    async function testAsync() {
        return Promise.resolve('hello2');
    }
    async function test() {
        let v1 = await test1();
        let v2 = await testAsync();
        console.log(v1, '----------------', v2)
    }
    test();
</script>

await是一个运算符,用于组成表达式,所以说之后的表达式的结果决定了它等待的时间。

如果它接受的一个结果是一个promise对象,await还需要阻塞其后的代码,等着promise对象去resolve.

但是却没有发现这两个的优势是什么,原因应该在于我们现在只是在考虑单一的promise链,没有改变为多个Promise组成的then链。

参考网上一个大捞的栗子:

<script>
    function takeLongTime(n) {
        return new Promise(resolve => {
            setTimeout(() => resolve(n + 200), n);
        });
    }

    function step1(n) {
        console.log('step1 with', n);
        return takeLongTime(n);
    }

    function step2(n) {
        console.log('step2 with', n);
        return takeLongTime(n);
    }

    function step3(n) {
        console.log('step3 with', n);
        return takeLongTime(n);
    }

    function doIt() {
        console.time('doIt');
        const time = 3000;
        step1(time)
            .then(time2 => step2(time2))
            .then(time3 => step3(time3))
            .then(res => {
                console.log('res=>>>>', res);
                console.timeEnd('doIt')
            })
    }
    doIt();
</script>

可以看出输出结果:

image-20201127174854545

基本上函数执行时间与函数统计时间一致。

如果使用async呢!!!

async function doIt01() {
        console.time('doIt01');
        const time1 = 3000;
        const time2 = await step1(time1);
        const time3 = await step2(time2);
        const res   = await step3(time3);

        console.log('res=>>>>', res);
        console.timeEnd('doIt01')
    }

image-20201127175344459

结果与then链的结果一致。

需要注意的!!

因为await命令后面追随着Promise对象,但是运行结果也有可能是rejected,所有还需要对await进行try..catch。

两种写法:

async function test(){
	try{
        await doIt();
	}catch(err){
        console.log(err);
    }
}
async function test(){
	 await doIt().catch(function(err){
         console.log(err);
     });
}

参考资料

阮一峰的网络日志

理解JavaScript的async以及await——边城

posted @ 2020-11-28 15:53  且I听  阅读(155)  评论(0)    收藏  举报