zoukankan      html  css  js  c++  java
  • 利用generator模拟协程完美解决异步回调问题

    一直不喜欢es6/7的promise、await、async之流对异步回调的解决方案,个人觉得类似lua里面协程的语法处理异步回调更顺眼,es6的generator虽然不完美,但是可以简单模拟一下协程。经过简单封装,完美解决异步回调的问题,要多个异步并行就并行,要串行就串行。
    直接上代码:

    /**
     * 执行生成器
     * @param {Generator} generator 生成器函数(this指针里面有next函数和genInst原始生成器实例,参数由args传入)
     * @param {Array} args 传递给生成器的参数数组(可以为空)
     * @param {Function} end 生成器执行完之后的回调函数(可以为空),参数为生成器的返回值
     */
    var runGenerator = function (generator, args, end){
        var co = {};
        var genInst;
        co.next = function (){
            var rsl = genInst.next.apply(genInst, arguments);
            if(rsl.done){
                end && end(rsl.value);
            }
        };
        genInst = generator.apply(co, args || []);
        co.genInst = genInst;
        co.next();
    };
    
    //测试异步函数
    var asyncTest = function (person, cb){
        setTimeout(function (){
            cb(undefined, "hi " + person);
        }, 1000);
    };
    
    runGenerator(function* (ctx, next){
        var _this = this;
        console.log("start");
        var recvArg = function (){
            //生成器的_this.next函数参数会在下一个yield点传出
            //js不支持多返回值,把参数当成数组,利用解构赋值来模拟
            _this.next(arguments);
        };
        asyncTest("John", recvArg);
        var [err, greeting] = yield;
        if(err){
            console.error(err);
        } else {
            console.log(greeting);
        }
        console.log("end");
    });

     补充:

    随着对promise了解的深入,对此问题有新的认识。promise解决的不是回调的缩进问题,解决的是回调的信任问题,generator才是解决回调缩进问题的方法。所以两者并不冲突,可以配合使用。

  • 相关阅读:
    设计模式之-----------单例设计模式
    ubuntu 14 编译视频第三方库ijkplayer,能够在winows下使用
    AMP Physical Link Creation And Disconnect
    AnimationEvent事件问题
    网络事件触发自己主动登录
    Learn from Architects of Buildings
    对软件测试团队“核心价值”的思考
    【转】Android开发调试工具ADB的使用
    【转】adb控台中Permission denied的解决方案
    【转】蓝牙ble app开发(三) -- 抓包
  • 原文地址:https://www.cnblogs.com/omega8/p/9605471.html
Copyright © 2011-2022 走看看