20200421

@xiaojingzhao

Plan

  • 你不知道的 js - 第三章 代码组织

Notes

生成器

生成器委托 -- yield 委托

  • 语法
yield * xxx; // xxx is iterable
function* foo() {
  yield* [1, 2, 3];
}

上面这个例子等价于

function* arry() {
  yield 1;
  yield 2;
  yield 3;
}

function* bar() {
  yield* arry();
}
  • 生成器中的 return

yield * 可以捕获生成器返回的值

function* foo() {
  yield 1;
  yield 2;
  yield 3;
  return 4;
}
function* bar() {
  var x = yield* foo();
  console.log("x: ", x); // x 最后被赋值成了 4
}

for (v of bar()) {
  console.log(v);
}
  • 生成器可以自己委托自己,产生递归
function* foo(x) {
  if (x < 3) {
    x = yield* foo(x + 1);
  }
  return x * 2;
}
foo(1); // 一次next,最终会输出24

迭代器控制

  • 可以通过给 next 传值来沟通
function* foo() {
  var x = yield 1;
  var y = yield 2;
  var z = yield 3;
  console.log(x, y, z);
}
var it = foo();
it.next(); // { value: 1, done: false}
it.next(); // { value: 2, done: false}
it.next(); // { value: 3, done: false}
it.next(); // { value: undefined, done: true}
// x = undefined; y = undefined; z = undefined

yield 之后跟着的值是 value 中的值,而不是给 x, y, z 赋值的值。如果想要给 x,y,z 赋值的话:

// 上面的例子
var it2 = foo();
it2.next(); // { value: 1, done: false}
it2.next("x"); // { value: 2, done: false}
it2.next("y"); // { value: 3, done: false}
it2.next("z"); // { value: 3, done: false}
// x = x; y = y; z = z

第一次不传值,因为第一次的 next 还没有运行到 x = xxx 之后,还停留在第一个 yield 等待的时候。

More