如何有条件地停止 JavaScript 生成器?

Tom*_*uer 7 javascript c# iterator generator

使用如下所示的迭代器:

function* idMaker(){
    let index = 0;
    while(index < 3)
        yield index++;
}
Run Code Online (Sandbox Code Playgroud)

如何确保根据情况提前停止发电机?

function* idMaker(){
    let index = 0;
    while(index < 3)
        if (checker(index))
            yield index++;
        else
            return;
}
Run Code Online (Sandbox Code Playgroud)

适合在发电机中使用吗?我应该使用break而不是yield break像 C# 中那样吗?

您能否提供一个 MDN 链接或讨论此问题的规范?

qui*_*mmo 5

您是否尝试过查看return生成器的方法?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/return

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('bar'); // { value: "bar", done: true }
Run Code Online (Sandbox Code Playgroud)


Tom*_*uer 3

我决定使用以下代码通过实验验证这一点:

function checker(i) {
  return i !== 2;
}

function* idMakerReturn(){
    let index = 0;
    while(index < 3)
        if (checker(index))
            yield index++;
        else
            return;
}

function* idMakerBreak(){
    let index = 0;
    while(index < 3)
        if (checker(index))
            yield index++;
        else
            break;
}

const a = idMakerReturn();
console.log('1', a.next());
console.log('2', a.next());
console.log('3', a.next());

const b = idMakerBreak();
console.log('1', b.next());
console.log('2', b.next());
console.log('3', b.next());
Run Code Online (Sandbox Code Playgroud)

{ "done": true, "value": undefined }两种变体在脱离时都能正确返回。我还通过观察推断的函数类型使用 TypeScript 检查了这一点。

function* idGen(seed: string | undefined) {
  if (!seed) {
    return; // Or `break`
  }

  const something = seed.trim();
}
Run Code Online (Sandbox Code Playgroud)

一切return正常,函数返回类型为IterableIterator<T>.

随着break我被要求提供一个要跳转到的标签,并且也something不再被推断为可以安全访问(只是string因为undefined是由 处理的if),但仍然是string | undefined.

这使我得出结论,正如 Felix 所说,任何终止生成器函数的操作都将正确生成该done: true项目,但这似乎return更可取,因为转义分析适用于它,而它不适用于break.

仍然无法找到这方面的官方消息,但这对我来说已经足够了。