如何理解async/await

256 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

1、是什么

async/await是ES7提出来的异步操作的解决方案。

2、解决了什么问题

我们都知道一个新特性的产生往往是为了解决之前存在的问题,那在async/await出来之前我们是怎么处理异步操作的呢?

  • 回调函数(存在回调地狱问题)
  • Promise(各种链式调用)
  • Generator(执行繁琐,需要借助co才能自动执行,否则得手动调用next) async/await的诞生,可以让你以同步风格的代码执行异步的操作,更加简洁,更加清晰。

3、怎么用

async是加在函数前面的一个修饰符,具体是怎样的呢,我们来试一下

async function fun() {
    return "Hello Word";
}
fun();

image.png

重点看一下返回结果,它返回的是一个Promise。那我直接跟一个then函数呢

async function fun() {
    return "Hello Word";
}
fun().then(res => {
    console.log(res);
})

image.png

如果async函数中有返回一个值 ,当调用该函数时,内部会调用Promise.solve()方法把它转化成一个promise对象作为返回,但如果函数内部抛出错误呢? 那么就会调用Promise.reject()返回一个promise对象

async function fun() {
    throw "Error";
}
fun();

image.png

async function fun() {
    throw "Error";
}
fun().catch(err => {
    console.log(err);
});

image.png

async了解之后再来看一下await,注意,await必须是在async函数内部。

function getFun() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve("获取成功");
        }, 2000)
    })
}
async function fun() {
    const res = await getFun();
    console.log(res);
}
fun();

image.png

就这一个函数,我们可能还看不出async/await的作用,多来几个

function getFun(num) {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(num);
        }, 2000)
    })
}
async function fun() {
    const res1 = await getFun(1);
    const res2 = await getFun(2);
    const res3 = await getFun(3);
    console.log(res1);
    console.log(res2);
    console.log(res3);
}
fun();

image.png

4、总结

  1. async用在一个函数最前面,await必须是在一个async函数内部。
  2. async函数返回的是一个Promise对象,如果结果是值,会经过Promise包装返回。
  3. 使用了await命令,则一定要await后面的代码执行完之后才会执行下面的代码,不管await后面是一个异步还是同步函数。正是因为这个命令,才让js的异步代码看起来像同步代码一样,从上至下依次执行。当异步操作之间不存在结果的依赖关系时,可以使用promise.all来实现并行。