async&await

JavaScript中异步从来都不简单,很长一段时间内, 我们都是使用的回调来实现。后来,我们可以使用promise,现在,我们可以使用asyncawait(以下简称异步函数)来实现异步。

虽然异步函数的出现使得编写异步函数更加容易了,但是同样也存在陷阱,并且对于初学者并不是那么的友好。

在这篇文章的两个部分中,我将和你们一起分享一切你需要知道的关于异步函数的知识。

Asynchronous functions

异步函数包含async关键字,你可以像普通的函数声明一样使用它:

    async function functionName (arguments) {
        //Do something asynchronous
    }

你也可以使用箭头函数

    const functionName = async (arguments) => {
        //Do something asynchronous
    }

Asynchronous functions always return promise

返回什么值并不重要,使用异步函数返回的值总是一个promise

    const getOne = async _ => {
        return 1;
    }

    const promise = getOne();
    console.log(promise) // Promise

await关键词

当你调用一个promise时,你使用then来进行下一步,就像这样:

    const getOne = async _ => {
        return 1;
    }

    getOne()
        .then(value => {
            console.log(value); // 1
        })

await关键词让你定义reslove函数,一旦promise成功了,它就会返回传递到then函数的参数。

    const test = async _ => {
        const one = await getOne();
        console.log(one);
    }

    test();

Return await

在返回一个promise之前,等待是没有必要的,你可以直接返回promise.

如果你返回一个await, 你先实现了原来的promise,然后,你又创建一个新的promise,return await虽然不影响什么,但是没有必要多此一举。

    //Don't need to do this
    const test = async _ => {
        return await getOne();
    }

    test()
        .then(value => {
            console.log(value); // 1
        })

    //Do this instead
    const test = aysnc _ => {
        return getOne();
    }

    test()
        .then(value => {
            console.log(value); //1
        })

注意,如果你不需要await,你不许要使用异步函数。上面的列子可重写。

    //Do this instead
    const test = _ => {
        return getOne();
    }

    test()
        .then(value => {
            console.log(value); // 1
        });

Handling errors

如果一个promise导致了错误,你可以使用catch来捕捉他

    const getOne = aysnc (success = true) => {
        if (success) return 1;
        throw new Error('failure');
    }

    getOne(false) 
        .then(error => console.log(error)); // failure

如果你想在异步函数中处理错误,你需要使用一个try/catch来捕捉它。

    const test = async _ => {
        try {
            const one = await getOne(false);
        }catch (e) {
            console.log(e); //failure
        }
    }

    test();

如果你有多个await关键词,这样写错误处理会变的很丑

    const test = async _ => {
        try {
            const one = await getOne(false);
        }catch (e) {
            console.log(e); //failure
        }

        try {
            const two = await getTwo(false);
        }catch (e) {
            console.log(e); //failure
        }

        try {
            const three = await getThree(false);
        }catch (e) {
            console.log(e); //failure
        }
    }

    test();

但是还有一个更好的办法。

我们知道异步函数总是返回一个promise,当我们调用一个promise,我们在catch中处理错误。这意味这我们可以通过添加catch来处理错误。

    const test = async _ => {
        const one = await getOne(false);
        const two = await getTwo(false);
        const three = await getThree(false);
    }

    test()
        .catch(error => console.log(error));

注意: Promise方法只会让你捕捉一个错误。

Multiple awaits

await会阻塞js执行下一行代码,知道promiseresolve被执行完成。这可能会降低执行的效率。

我们需要创建一个延迟来在实际中演示,通过sleep来创建延迟。

    const sleep = ms => {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    //Using Sleep
    console.log('Now');
    sleep(1000)
        .then(value => console.log('after one second')); // print 'now' immediately, 'after one second' printed in console after 1 second

现在我们来看需要等三个promise的情况,每一个promise都有一个一秒的延迟。

    const getOne = _ => {
        return sleep(1000).then(val => 1)
    }

    const getTwo = _ => {
        return sleep(1000).then(val => 1)
    }

    const getThree = _ => {
        return sleep(1000).then(val => 1)
    }

如果你await这些promises在一行中,你将不得不等待3秒在那些promise全部结束之前。这不是很好因为我们强迫JavaScript等待额外的2秒在做我们需要的之前。

    const test = async _ => {
        const one = await getOne();
        console.log(one);

        const two = await getTwo();
        console.log(two);

        const three = await getThree();
        console.log(three);

        console.log('Done');
    }

    test(); //Console shows ‘Now’ immediately. One second later, it shows 1. Another second later, it shows 2. Another second later, it shows 3 and ‘Done’ at the same time.

如果getOne, getTwo, getThree可以同时(simultraneously)执行,你可以节省两秒。你可以使用promise.all同时执行三个promise.

    const test = async _ => {
        const promise = [getOne(), getTwo(), getThree()];
        console.log('Now');

        const [one, two, three] = await Promise.all(promise);
        console.log(one);
        console.log(two);
        console.log(three);

        console.log('Done');
    };

Console shows ‘Now’ immediately. After one second, console shows 1, 2, 3, and ‘Done’

欢迎补充。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值