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();