JavaScript的async和await
1. async函数
async
函数是使用async
关键字声明的函数。async
函数一定会返回一个 promise
对象。
await
关键字只在 async
函数内有效,await
表达式会暂停整个 async
函数的执行进程并出让其控制权,只有当其等待的基于 promise
的异步操作被兑现或被拒绝之后才会恢复进程。
async
和 await
关键字可以用一种更简洁的方式写出基于 Promise
的异步行为,而无需刻意地链式调用 promise
。
使用 async
/await
关键字就可以在异步代码中使用普通的 try
/catch
代码块。
2. 基本使用
// 声明一个异步函数
async function test() {
try {
// 等待执行结果
await new Promise( (resolve, reject) => {
// 进行异步操作
setTimeout( () => {
let num = Math.ceil(Math.random() * 20);
if (num > 10) {
resolve(`${num} > 10,执行成功!`);
} else {
reject(`${num} <= 10,执行失败!`);
}
},1000 );
} );
// 等待执行结果
await new Promise( (resolve, reject) => {
// 进行异步操作
setTimeout( () => {
let num = Math.ceil(Math.random() * 20);
if (num > 10) {
resolve(`${num} > 10,执行成功!`);
} else {
reject(`${num} <= 10,执行失败!`);
}
},1000 );
} );
} catch (err) {
// 只要有一个Promise的状态从pendding->rejected,就会走catch
console.log(err)
}
}
3. async/await与Promise对比
3.1 不含await
async function test() {
return 1;
}
等价于
function test() {
return Promise.resolve(1);
}
async
函数一定会返回一个 promise
对象。如果一个 async
函数的返回值看起来不是 promise
,那么它将会被隐式地包装在一个 promise
中。
3.2 含await
async function test() {
await 1;
}
等价于
function test() {
return Promise.resolve(1).then(() => undefined);
}
async
函数的函数体可以被看作是由 0 个或者多个await
表达式分割开来的。从第一行代码直到第一个 await 表达式都是同步运行的。- 一个不含
await
表达式的async
函数是会同步运行的。然而,如果函数体内有一个await
表达式,async
函数就一定会异步执行。 - 在
await
表达式之后的代码可以被认为是存在在链式调用的then
回调中,多个await
表达式都将加入链式调用的then
回调中,返回值将作为最后一个 then 回调的返回值。