AsyncFunction对象于2016年进入ECMAScript提议的stage 4阶段,并会于2017年被纳入语言标准(ECMAScript 2017当前已处于起草阶段),成为ECMAScript的标准内置对象。最新版本的Chrome(55+)、Firefox(52.0+)、Node.js(7.6.0+)已提供了对该对象的支付,本篇简单介绍和使用该对象。
1. AsyncFunction对象
JavaScript中的每个异步函数实际上都是AsyncFunction对象。创建一个AsyncFunction对象可以使用AsyncFunction构造函数,也可以使用async function表达式。
AsyncFunction构造函数
new AsyncFunction([arg1[, arg2[, ...argN]],] functionBody)
参数
arg1, arg2, ... argN:函数参数,字符串形式functionBody:函数声明,函数语句字符串
使用AsyncFunction构造函数创建AsyncFunction实例时需要注意以下两点:
- 函数体是字符串形式,这和使用
Function构造函数创建普通函数的结构是一样 AsyncFunction并不是全局对象,需要通过以下语句来获取对它的引用:var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
AsyncFunction构造函数的使用
使用AsyncFunction构造函数创建一个异步函数:
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
var a = new AsyncFunction('a',
'b',
'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);');
a(10, 20).then(v => {
console.log(v); // 4秒后,输出 30
});
异步函数调用时会返回一个promise对象。当其返回的一个值时,promise的resolve方法会处理这个返回值;当异步函数抛出的是异常或者非法值时,promise的reject方法会处理这个异常值。
除resolved和rejected状态外,promise还可能会处于pending(等待)状态。这时可以在异步函数中使用await表达式,await会使异步函数暂停执行并等待promise解析传值后,继续执行异步函数并返回解析值。
2. async function表达式
从前面示例可以看出,AsyncFunction构造函数创建对象时操作比较麻烦,而且执行效率也不高。因此,更推荐使用async function表达式。
使用async function表达式创建AsyncFunction对象的语法结构如下:
async function name([param[, param[, ... param]]]) {
statements
}
使用示例
使用async function表达式重写前面构造函数创建的异步函数:
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function a(a, b) {
return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);
}
a(10, 20).then(v => {
console.log(v); // 4秒后,输出 30
});
3. await表达式
await表达式会在异步函数内部使用,它会暂停异步函数的执行并且等待promise返回resolved或rejected状态值。
当返回resolved状态值时,异步函数会恢复执行并返回resolved 值。如果返回的值不是一个promise,那么它将会被转换成一个resolved后的promise
如果返回promise是rejected状态,则await表达式会抛出异常值。
await使用示例
当一个promise被传给await表达式时,它将会等待promise处理完成并返回resolved值:
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
var x = await resolveAfter2Seconds(10);
console.log(x); // 10
}
f1();
即使返回值不是promise,也会被转换为一个resolved状态的promise:
async function f2() {
var y = await 20;
console.log(y); // 20
}
f2();
如果返回的是rejected状态的promise,那么异常会被抛出:
async function f3() {
try {
var z = await Promise.reject(30);
} catch (e) {
console.log(e); // 30
}
}
f3();
