基本概念
async
The
async function
declaration defines an asynchronous function — a function that returns anAsyncFunction
object. Asynchronous functions operate in a separate order than the rest of the code via the event loop, returning an implicitPromise
as its result. But the syntax and structure of code using async functions looks like standard synchronous functions.
MDN上是如此定义async函数的,翻译过来基本就是async定义了一个异步函数,这个函数隐式返回一个Promise对象,但是这个异步函数写起来看着就跟普通的同步函数差不多。
举个例子
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
};
var add = async function(x) { // async function expression assigned to a variable
var a = await resolveAfter2Seconds(20);
var b = await resolveAfter2Seconds(30);
return x + a + b;
};
add(10).then(v => {
console.log(v); // prints 60 after 4 seconds.
});
我们把add通过在function前面增加async来定义成了一个异步函数,然后我们调用add的时候,直接把返回值当做Promise对象来处理。
await
The
await
operator is used to wait for aPromise
. It can only be used inside anasync function
.
MDN上面的定义很简单,翻译过来就是
await
操作符用来声明等待一个Promise
。 它只能出现在有async修饰的函数当中。
await操作符等待结束后返回的是一个Promise对象resolve(fulfilled状态)后的值,如果不是一个Promise,那么引擎也会自动转换成一个已经resolve的Promise对象然后把值返回。如果是Promise对象最后是rejected状态,那么我们需要用try catch或者直接使用Promise的catch方法来捕获。
- await一个Promise
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
var x = await resolveAfter2Seconds(10);
console.log(x); // 10
}
f1();
- await一个非Promise
async function f3() {
var y = await 20;
console.log(y); // 20
}
f3();
- await的Promise是rejected状态,使用try catch捕获
async function f4() {
try {
var z = await Promise.reject(30);
} catch(e) {
console.error(e); // 30
}
}
f4();
- await的Promise是rejected状态,使用Promise的catch方法捕获
async function f5() {
await Promise.reject(30);
}
f5().catch(e => console.error(e)); // 30
async/await与Promise的关系
async和await可以理解成对异步编程的一个新的语法糖,从上面的例子我们可以看出它其实是基于Promise而提供的这些新特性。这一对修饰符的提供,目的非常明确,就是让我们的异步编程看起来好像是在编写同步程序一样,完全不需要写很深的callback,也不需要写很长的链式操作。
一些注意事项
- await一定要写在async修饰的函数内部。
- async/await处理单一,或者前后依赖的多个异步请求的时候是最适合的,但并不适合并发、竞争等等情况下的多个异步请求。例如Promise.all() 或者 Promise.race()提供的能力,我们是不能通过await来把所有的请求依次写下来的,因为这样会把并发请求编程线性请求,严重拉长请求时间。