开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第30天,点击查看活动详情
async-await
async-await是ECMA17提出来的基于promise对象的语法糖。可以让异步操作更加地明了。通过使用async关键字将函数标记为异步函数(也就是promise对象的函数),然后在异步函数中调用其他的异步函数,这时是使用await语法调用这个异步函数。
await会等待promise完成之后直接返回最终的结果。
通俗地讲就是async是用来定义异步函数的,而await必须用在async定义的异步函数中,用于等待一个 Promise兑现并获取它兑现之后的值。
1. async关键字
- 定义异步函数
- 返回类型为Promise的对象
- 无阻塞,不等待,在没有await的情况下执行async函数,它会立即执行,返回一个Promise对象,并且绝对不会阻塞后面的语句,这和普通返回Promise对象的函数一样。
async function fun() {
return Promise.resolve('好好学习!');
}
2. await关键字
- 只能在async函数内部使用
- await关键字紧跟Promise对象
- 后面可以写同步代码
- await是async wait的意思: wait的是resolve()的消息,并把数据data返回,比如下面代码中,当Promise对象由Pending变为Resolved的时候,就执行await这个语句,然后再顺序执行下面的语句。这点有点类似于同步代码的执行。
- await对于失败消息是不会处理的,因此一般采用下面方式处理
- 让await后面的Promise对象自己catch
- 让外面的async函数返回的Promise对象统一catch
- 放在try...catch中
// 让await后面的Promise对象自己catch
const response = await promisedFunction().catch((err) => {
console.error(err);
return "default response";
});
// 让外面的async函数返回的Promise对象统一catch
async function fun() {
return Promise.resolve('好好学习!');
};
fun.catch((err) => {
console.error(err);
});
// 放在try...catch中
async function f4() {
try {
const z = await Promise.reject(30);
} catch (e) {
console.error(e); // 30
}
}
async-await在使用时需要注意的坑
1. async中的用到两个await函数,这样第一个函数会影响到后面函数的执行
async function fun() {
const a = await fetch('http://.../1');
const b = await fetch('http://.../2');
}
这时第一个await函数会阻塞第二个await函数的执行,也就是说第一个await函数没有执行完的话是不会执行第二个await函数的。
这时最高效地做法是将所有promise用promise.all组合起来,然后再使用await。
async function fun() {
const promiseA = fetch('http://.../1');
const promiseB = fetch('http://.../2');
const [a, b] = await Promise.all([promiseA, promiseB]);
}
2. 在循环中执行异步操作,是不能直接调用forEach或者map这一类方法
async function fun() {
[1, 2, 3].forEach(async (i) => {
await asynFunc();
});
console.log('I done');
}
在上述函数中,即使我们写了await,但是它并不会暂停等到所有异步操作都执行完成,而是立即返回forEach的执行结果。
如果我们想要在循环中执行异步操作应该使用传统的for循环
async function fun() {
let arr = [1, 2, 3];
for ( let i = 0; i < arr.length; i++) {
await asynFunc();
}
console.log('I done');
}
或者使用for await关键字,这时for循环依然会等到所有的异步操作都完成之后才继续向后执行。
async function fun() {
let arr = [1, 2, 3];
for await ( let i of arr) {
asynFunc();
}
console.log('I done');
}
3. 不能在全局或者普通函数中直接使用await关键字
await asynFunc();
await只能使用在async异步函数中,如果我们想要在最外层中使用await,需要先定义一个异步函数,然后在函数体中使用它。
async function fun() {
await asynFunc();
}