yield 与 yield*介绍

一、yeild关键字

  1. ES6的新关键词, 用来使生成器函数执行、暂停
  2. yield关键字后面的表达式的值返回给生成器的调用者
  3. yield关键字返回一个 迭代器对象 { value:xxx, done:xxx },
  •          value: xxx当前遍历器暂停时返回的结果,
    •          done:boolean false表示遍历器未结束, true表示遍历器已结束
  1. yield无法单独工作, 需要配合generator(生成器)的其他函数, 如next(), 懒汉式加载...

1、yeild并不能直接生产值, 而是产生一个等待输出的函数

var f = function *(){
  var x = 1;
  var y = yield(x+1);
  console.log(y)
  var z = yield(x+y);
  console.log(z)
  return z;
}
const fGeno = f() 
console.log(fGeno.next()) 
console.log(fGeno.next(3))
console.log(fGeno.next(4))

运行结果:

  1. 第1次执行暂停与yield(x+1)。返回(x+1)等于2
  2. 第2次执行暂停与yield(x+y)。next(3)中的参数3作为上一个yeild执行结果即 y=3, 所以z=4
  3. 第3次执行暂停与return z。等于4

2、next()可以带一个参数,该参数会被认为是上一个yield整体的返回值

function* counter(value) {
 let step;
 while (true) {
   console.log('qqqqqq  ', value, step)
   step = yield ++value;
   console.log('ddddd  ', value, step)
   if (step) {
     value += step;
     console.log('vvvvvv  ', value, step)
   }
 }
}
const generatorFunc = counter(0);
console.log(generatorFunc.next().value);   // 1
console.log(generatorFunc.next().value);   // 2
console.log(generatorFunc.next().value);   // 3
console.log(generatorFunc.next(10).value); // 14
console.log(generatorFunc.next().value);   // 15
console.log(generatorFunc.next(10).value); // 26

运行结果:

图片中的1、2、3、4、5、6 对应以上的console.log()顺序
注意:next()可以带一个参数,该参数会被认为是上一个yield整体的返回值参看第4个console.log()

3、遍历器函数中的for..of

function *foo(){
  yield 1;
  yield 2;
  yield 3;
  return;
}
for(let v of foo()){
  console.log(v);
}
// 1
// 2
// 3

二、yeild*表达式

  1. yield* [[expression]] expression:是可遍历对象,可以是数组、字符串、Generator函数的执行表达式等等
  2. yield*返回一个可迭代对象的表达式

1、yield* 是一个表达式,不是语句,所以它会有自己的值。

function* g4() {
  yield* [1, 2, 3];
  return "foo";
}
var result;
function* g5() {
  result = yield* g4();
}
var iterator = g5();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true },
                              // 此时g4()返回了{value:"foo",done: true}
console.log(result);          // "foo"

2、yield* 还可以 yield 其它任意的可迭代对象,比如说数组、字符串、arguments 对象等等

function* g3() {
  yield* [1, 2];
  yield* "34";
  yield* arguments;
}

var iterator = g3(5, 6);

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

三、yield 与 yield*区别

1、g1() yield 出去的每个值都会在 g2() 的 next() 方法中返回,就像那些 yield 语句是写在 g2() 里一样

function* g1() {
  yield (1 + 1);
  yield 3;
  yield 4;
}
function* g2() {
  yield 1;
  yield* g1();
  yield 5;
}
var iterator = g2();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

2、把上面g2()方法中的yield* g1() 改为yield g1() ,输出结果截然不同...

function* g1() {
  yield (1 + 1);
  yield 3;
  yield 4;
}
function* g2() {
  yield 1;
  yield g1();
  yield 5;
}
var iterator = g2();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值