Skip to content

Generator

js
function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

generator function 函数与常规函数不同。
generator function 不会运行代码,而是返回一个被称为 “generator object” 的特殊对象。
generator object 用来管理执行流程。

generator object 的主要方法是 next() ,当 next() 被调用时候,它会恢复 到 最近的 yield。 然后 函数暂停 , 并产出的(yielded)值。

yield 返回的值,为 { value:任意类型 , done:Boolean }

js
const generator = generateSequence();

generator.next();
// { value: 1, done: false }

return 3yield 3 一样,只是除此之外 return 还将 done 变为 true

generator function 可以没有 return。

generator object 是可迭代的

js
function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

for (let value of generateSequence()) {
  console.log(value);
  // 1
  // 2
}

没有 3,因为 3 的 done 为 true。

“yield” 是一条双向路

js
function* gen() {
  let result = yield "2 + 2 = ?";
  return result;
}

let generator = gen();
let question = generator.next();
//  { value: '2 + 2 = ?', done: false }

generator.next(4);
// { value: 4, done: true }

generator.return

主动 return

js
function* gen() {
  yield 1;
  yield 2;
  yield 3;
}

const g = gen();

g.next(); // { value: 1, done: false }
g.return("foo"); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }

g.return("2333"); // { value: '2333', done: true }

generator.throw

主动抛出错误

js
let generator = gen();
generator.throw(new Error());

rest

js
[0, ...generateSequence()];

composition

generator function 可以进行组合,彼此“嵌入(embed)”到一起

js
function* generateSequence(start, end) {
  for (let i = start; i <= end; i++) yield i;
}

function* generatePasswordCodes() {
  // 0..9
  yield* generateSequence(48, 57);

  // A..Z
  yield* generateSequence(65, 90);

  // a..z
  yield* generateSequence(97, 122);
}

例子

js
function* range(from, to) {
  for (let i = from; i < to; i++) {
    yield i;
  }
}

for (const i of range(1, 5)) {
  console.log(i);
}
js
const range = {
  *[Symbol.iterator]() {
    const from = 1;
    const to = 5;

    for (let i = from; i <= to; i++) {
      yield i;
    }
  },
};

for (let value of range) {
  console.log(value);
}

async 异步相关

js
const test = {
  [Symbol.iterator]() {
    // 正常状况下
  },

  [Symbol.asyncIterator]() {
    // 异步状况下
  },
};

Symbol.asyncIterator 的 next() ,应该是 promise !!

js
async function* generateSequence(start, end) {
  for (let i = start; i <= end; i++) {
    // 可以 使用 await !
    await new Promise((resolve) => setTimeout(resolve, 1000));

    yield i;
  }
}
js
let generator = generateSequence(1, 5);
for await (let value of generator) {
  alert(value); // 1,然后 2,然后 3,然后 4,然后 5(在每个 alert 之间有延迟)
}

todos

省略一些内容

省略 https://www.yuque.com/qinsjs/jsinfo/qoeo6mnntnanb7uz