ES8中,异步的最终解决方案,是Generator和promise的语法糖,以同步的形式编写异步代码
async asyncFunction (params) {const data = await promiseFunc(params)return data}asyncFunction()
async函数
用async关键字修饰一个函数,修饰后叫作async函数
async function asyncFunc (value) {if ( value === 'promise' ) {return Promise.reject(777)}if ( value === 'other' ) {return value}throw new Error('错了')}
- async函数的返回值是一个promise,状态和值由函数执行结果决定
- 返回promise:直接使用该promise的状态和值
- 返回非promise:状态变为fulfilled,值为return的结果
- 抛出错误:没有捕获,状态变为rejected,值为错误信息
- async的执行时同步的,但是遇到await时,会暂停执行等待promise的结果(Generator)
await关键字
await右边是一个表达式,用来等待一个promise,只能在async函数中使用
const test = value => valueasync function asyncFunc () {const result1 = await promise.resolve(777) // result1 === 1const result2 = await ( 7 + 1 ) // result2 === 8const result3 = await test(9) // result3 === 9}
- await右边可以是任意表达式,并返回不同结果
- 是promise:返回promise成功状态的结果
- 不是promise:直接返回这个表达式的结果
执行流程
- 开始同步执行代码,遇到await时,先执行完await右边的表达式,然后中断函数,释放线程
- await会根据表达式的结果,将await表达式进行替换,然后将剩余代码放入微队列中
- 等待的promise:继续等待,当状态发生改变后再进行操作
- 成功的promise:替换为promise的结果
- 失败的promise:替换为错误抛出语句,错误信息是promise的结果
- 非promise:替换为该结果
- 就是根据结果创建一个promise,并在对应回调中调用
generator.next/throw()
错误处理
async asyncFunction (params) {try {const data = await Promise.reject(params)return data} catch (err) {console.log('出错了')}}
- async函数中可以直接通过
try...catch...捕获错误,进行处理
模拟实现
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里
- async就是Generator,await就是yeild ```javascript async function fn(args) { // … }
// 等同于
function fn(args) { return spawn(function* () { // … }); }
- 所有的async函数都能写成第二种形式,而spawn就是自动执行器```javascriptfunction spawn(genF) {return new Promise(function(resolve, reject) {const gen = genF();function step(nextF) {let next;try {next = nextF();} catch(e) {return reject(e);}if(next.done) {return resolve(next.value);}Promise.resolve(next.value).then(function(v) {step(function() { return gen.next(v); });}, function(e) {step(function() { return gen.throw(e); });});}step(function() { return gen.next(undefined); });});}
