你还可以定义异步函数, 使用一个 async function expression 。
语法
async function name([param[, param[, ... param]]]) {
statements
}
name- 方法的名称。
param- 要传递给函数的参数的名称。
statements- 这些包含了方法体的语句。
描述
调用异步函数时会返回一个 promise 对象。当这个异步函数返回一个值时,promise 的 resolve 方法将会处理这个返回值;当异步函数抛出的是异常或者非法值时,promise 的 reject 方法将处理这个异常值。
异步函数可能会包括 await 表达式,这将会使异步函数暂停执行并等待 promise 解析传值后,继续执行异步函数并返回解析值。
例如
简单例子
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function add1(x) {
var a = resolveAfter2Seconds(20);
var b = resolveAfter2Seconds(30);
return x + await a + await b;
}
add1(10).then(v => {
console.log(v); // prints 60 after 2 seconds.
});
async function add2(x) {
var a = await resolveAfter2Seconds(20);
var b = await resolveAfter2Seconds(30);
return x + a + b;
}
add2(10).then(v => {
console.log(v); // prints 60 after 4 seconds.
});
通过异步方法重写 promise 链
返回 promise 的 API 将会被用于 promise 链,它会将方法分成若干部分。例如下面代码:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch(e => {
return downloadFallbackData(url) // returns a promise
})
.then(v => {
return processDataInWorker(v); // returns a promise
});
}
可以通过一个异步函数改写为:
async function getProcessedData(url) {
let v:
try {
v = await downloadData(url);
} catch (e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
注意,在上面的例子中返回语句中没有 await ,因为 Promise.resolve 会隐式包裹异步方法的返回值。
规范
| Specification | Status | Comment |
|---|---|---|
| ECMAScript Async Functions async function |
Draft | Proposal |
兼容性
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Edge | Opera | Safari (WebKit) |
|---|---|---|---|---|---|---|
| Basic support | 55 | 52.0 (52.0) | ? | ? | 42 | ? |
| Feature | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
|---|---|---|---|---|---|---|---|
| Basic support | 未实现 | 未实现 | 52.0 (52.0) | ? | 42 | ? | 55 |