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