写一个简单的generator执行器

对generator不熟悉的可以先看下相关的基础资料

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Generator

在早些时候,generator + promise 可以比较优雅的解决JS中较为头痛的回调嵌套问题,并且为了解决让 generator 能够自动执行的问题,出现了诸如co这样的模块,在这里自己简单的实现一版,探索一下其中的原理,首先要解决几个问题。
  1. 自执行
    自执行的关键就是要在每一个异步的回调中,去调用iterator的next方法,并且传入相应回调的参数。用递归的思路可以较好解决,这里要注意的是,yield 后面可以跟上同步操作,这种情况我也统一包装成了promise返回。

  2. yield 后面跟的是一个promise数组
    当有多个异步任务时,这里会利用Promise.all 来处理这个情况,最终返回一个结果数组,注意下 promise 数组的判断就好。

  3. 在这个自执行方法执行完后,需要返回一个promise,可以继续调用then方法,这个只需要在最开始返回一个promise即可。

示例如下

function run (genFn) {
    let it = genFn();
    let store = it.next();

    return new Promise((resolve,reject)=>{
        function next () {
            if (store.done) resolve(store.value);
    
            // 如果是promise数组
            if (isPromiseArray(store.value)){
                Promise.all(store.value).then((retArray)=>{
                    store = it.next(retArray);
                    next();
                }).catch(e => reject(e.message));
            } else {
                // 因为每一个步骤可能是异步,也可能是同步,这里统一转化为Promise来处理
                if (!(store.value instanceof Promise)) store.value = Promise.resolve(store.value).catch((e => console.log(e.message)));
                            
                store.value.then((ret) => {
                    store = it.next(ret);
                    next();
                }).catch(e => reject(e.message));
            }
        }
    
        function checkType(variable){
            return Object.prototype.toString.call(variable).slice(8,-1).toLowerCase();
        }
    
        function isPromiseArray (array) {
            if (!(checkType(array) === 'array')) return false
            let flag = true;
            for (let i=0; i<array.length;i++) {
                if (!(array[i] instanceof Promise)){
                    flag = false;
                    break;
                } 
            }
            return flag;
        }
    
        next();
    });
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值