aysnc/await的简单实现

315 阅读1分钟

1.什么是async?

async函数是什么?一句话,它就是 Generator 函数的语法糖。

2.async相对于Generator函数的改进

在笔者读完ES6文档和async在babel中具体被编译成什么样子后,有如下总结:
Generator函数式不会自执行的,需要调用next()函数,在封装async的时候,究其本质
就是为Generator函数封装了一个内置的自动执行器,并将返回结果处理为Promise

3.实现

在清楚封装async函数的本质之后,可以给出以下代码:
async语法糖实现的两个关键点:
   1.返回的必须是一个promise对象
   2.使用递归函数实现yield表达式自执行  
/**
 * 自执行Generator并返回一个Promise对象
 * @param {*} fn 传入的generator函数块
 * @returns 
 */
function asyncToGenerator(fn){
  return function(){
    const generatorFunc  =  fn.call(this,arguments);//在generator函数的this指向当前作用域
    //返回Promise
    return new Promise((resolve,reject)=>{
        function step(key,arg){
              let generatorResult;
              try{
                generatorResult =  generatorFunc[key](arg);//向generator中的next()传入的参数 会被作为上一个yield表达式的返回值 
              }catch(e){
                reject(e);//reject generator函数执行的错误
              }
              //generator函数执行next()会返回一个{value,done}形式的对象 value是yield表达式的返回值 done表示所有yield表达式是否执行完
              const {done,value} = generatorResult;
              if(done){
                resolve(value)
              }else{
                return Promise.resolve(value).then(function onResolve(value){
                  step('next',value);
                },function onReject(reason){
                  step('throw',reason);
                })
              }
            }
        step('next');//第一次传递arg参数无效
    })
  }
}