generator 本质上并不能将异步代码做成同步的,仅仅能够控制代码的执行顺序,要实现异步代码执行起来像是同步的,需要类似co 和 thunkify 的库
co 的根本目的:将上一个yield 函数的回调返回值 作为下一个 next 函数的入参传递,实现代码看起来像是同步的
最终实现的如下 类似同步 风格代码
var a= yield 异步函数();
下面通过步骤演示co实现的本质:
最原始的异步变为同步方法1
function yibu1() { setTimeout(function(){
// 将yibu1 的值 作为下一个next 的入参 g.next("1"); },300) } function yibu2() { setTimeout(function(){ g.next("2"); },300); } function * doit() { var a = yield yibu1(); console.log(a); var b = yield yibu2(); console.log(b); return "hehe"; } var g = doit(); g.next();
----------------------------------------------
方法一在异步函数中依赖全局的generator,实际生活中是不可用的,下面是改进版本
// 模拟一个异步回调函数 function yibu1(cb) { setTimeout(function () { cb("1"); }, 300); } // 模拟一个异步回调函数 function yibu2(cb) { setTimeout(function () { cb("2"); }, 300); } function * doit() {// yield 后面跟的是一个函数 var a = yield yibu1; console.log(a); var b = yield yibu2; console.log(b); return "over"; } var g = doit(); // 目的 :将上一个函数回调的返回值 作为下一个next 的入参// value 是一个yibu1 函数 g.next().value(function (r) { g.next(r).value(function (rr) { console.log(g.next(rr).value); }) })--------------------------------------------------如上第二个改进版本依然有一个问题,需要知道generator 有多少个yield,最终版本如下(最简单的co版本)使用递归,递归的结束条件是返回值的done为false// 模拟一个异步回调函数 function yibu1(cb) { setTimeout(function () { cb("1"); }, 300); } // 模拟一个异步回调函数 function yibu2(cb) { setTimeout(function () { cb("2"); }, 300); } function * doit() { var a = yield yibu1; console.log(a); var b = yield yibu2; console.log(b); return "over"; } var gen = doit(); function next(result) { var step = gen.next(result); if (!step.done) { step.value(next); } else { console.log( step.value); } } next();