• 利用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才是解决回调缩进问题的方法。所以两者并不冲突,可以配合使用。

  • 相关阅读:
    POJ 2018 二分
    873. Length of Longest Fibonacci Subsequence
    847. Shortest Path Visiting All Nodes
    838. Push Dominoes
    813. Largest Sum of Averages
    801. Minimum Swaps To Make Sequences Increasing
    790. Domino and Tromino Tiling
    764. Largest Plus Sign
    Weekly Contest 128
    746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/omega8/p/9605471.html
Copyright © 2020-2023  润新知