es6 --- > 使用生成器交替执行

考虑以下场景:

var a = 1;
var b = 2;

function foo(){
    a++;
    b = b * a;
    a = b + 3;
}

function bar(){
    b--;
    a  = 8 + b;
    b = a * 2;
}

foo();
bar();
console.log(a, b);   // 11 22

bar();
foo();
console.log(a, b);    // 183 180

对于上面的两个函数foo和bar,它们中的任何一个,一旦开始了就会一直执行下去直至完毕.
倘若,我们想在foo中a++后,暂停一下在去执行bar中的某个语句… 可以使用ES6提供的yield语句.
改变如下:

var a = 1;
var b = 2;

function *foo(){    // *是生成器的标志
    a++;
    yield;
    b = b * a;
    a = (yield b) +3;
}

function *bar(){
    b--;
    yield;
    a = (yield 8) + b;
    b = a * (yield 2);
}

// 调用:foo执行完,在执行bar()
var s1 = foo();   // 初始化迭代器.
s1.next();  
console.log(a, b);  // 2 2 
s1.next();
console.log(a, b);  // 2 4

// 还有最后一个 a = (yield b) + 3;
s1.next();   // "预计"执行后会得到 7 4 
console.log(a, b);  // 实际上  NaN  4

// 诶????
// 实际执行yield b时,并得不到b的值因此会返回NaN. 于是a就是NaN

// 改进如下(foo中有2个yield, 因此会有3个next)
var s1 = foo();
var val1 = s1.next().value;
console.log(a, b);
val1 = s1.next(val1).value;
console.log(a, b);
val1 = s1.next(val1).value;
console.log(a, b);

// 运行bar,(bar中有3个yield,会有4个next调用)
var s2 = bar();  
var val2 = s2.next().value;
console.log(a, b);
val2 = s2.next(val2).value;
console.log(a, b);
val2 = s2.next(val2).value;
console.log(a, b);
val2 = s2.next(val2).value;
console.log(a, b);

在这里插入图片描述
可以看到,和正常函数执行结果是一样的…
还注意到.上述好多赋值语句是重复的,因此可以考虑构造一个辅助函数step,用于将yield返回的值原样的传入.

// step
function step(gen){
    var it = gen();
    var last;
     
    return function(){
        last = it.next(last).value;
    }
}

接下来使用step,先执行bar,后执行foo

var s1 = step(bar);
var s2 = step(foo);

s1();  //  1   1 
s1();  //  1   1
s1();  //  9   1
s1();  //  9   18
s2();  //  10  18
s2();  //  10  180
s2();  //  183 180

回归主题,交替执行bar和foo

var s1 = step(foo);
var s2 = step(bar);

s2();  // b--  ,yield
s2();  // yield 8
s1();  // a++, yield
s2();  // a = 8 + b, yield 2
s1();  // b= b * a,  yield b
s1();  // a = b + 3
s2();  // b = a * 2

可以看到,bar 和foo 都经过了多次的停止与启动,且它们之间进行了交替操作.
参考《你不知道的JavaScript》(中卷)P241~P242

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值