异步函数是 ES8 新增的,旨在解决利用异步结构组织代码的问题。
异步函数是 ECMAScript 对函数的扩展,是 ES6 期约在函数中的应用。
异步函数主要用于异步执行复杂任务,即执行时间较长的任务。
主要参考资料:
- 《JavaScript 高级程序设计(第4版)》- P347(372/931)
定义异步函数
通过在函数定义前使用关键字 async ,定义异步函数。
示例:
- 定义异步函数
// 命名函数 async function asyncFunc_01() { } // 匿名函数 const asyncFunc_02 = async function() { } // 箭头函数 const asyncFunc_03 = async () => { }
调用异步函数
调用异步函数,异步函数的返回值始终是一个期约。
异步函数返回期约的状态:
- 待定
在异步函数中返回一个待定期约。
(根据 JavaScript 引擎的具体实现,或者还有其它情形)
- 解决
在异步函数中返回解决期约。
解决期约会被镜像生成一个新的解决期约,异步函数返回新的解决期约。
在异步函数中返回非期约值。
非期约值会被方法 Promise.reolve() 包装生成一个解决期约,异步函数返回这个解决期约。
没有在异步函数中返回值。
通过方法 Promise.reolve() 会包装一个 undefined 值生成一个解决期约,异步函数返回这个解决期约。
- 拒绝
在异步函数中抛出错误。
异步函数返回一个拒绝期约,拒绝期约的理由为抛出的错误。
在异步函数中返回拒绝期约。
拒绝期约会被镜像生成一个新的拒绝期约,异步函数返回新的拒绝期约。
异步函数期待在函数体内返回一个实现接口 Thenable 的对象(例如:期约)。
在异步函数中返回的 thenable 对象会被解包。
- 主要对象:
thenable 对象的方法 then(callback)
- 解包效果:
- 执行方法 then() 中除调用 callback() 之外的语句。
方法 then() 的返回值会被忽略
- 取出方法 then() 中第一次调用 callback() 时传入的第一个参数的值,作为异步函数的返回期约的值
thenable 对象方法 then() 中其它调用 callback() 的语句会被忽略。
解包是异步执行的。
示例:
-
调用异步函数,异步函数的返回值是一个期约。
async function asyncFunc() { return 'value' } const returnedValue = asyncFunc() // 调用异步函数 setTimeout(console.log, 0, 'returnedValue:', returnedValue) // 输出: // returnedValue: Promise {<fulfilled>: 'value'}
-
在异步函数中抛出错误。
async function asyncFunc() { throw 'error' // 抛出错误 } const returnedValue = asyncFunc() returnedValue.catch( (reason) => { console.log('rejected is resolved:', reason) } ) setTimeout