【问题标题】:How do you terminate an 'infinite' generator in JavaScript?如何终止 JavaScript 中的“无限”生成器?
【发布时间】:2020-08-05 20:23:22
【问题描述】:

编辑:我进行了编辑以包含更多实际代码,看来我的“精简”示例有点令人困惑。

我有一个 javascript 数组,questions,长度未知,其中包含对象,每个“问题”一个,每个问题都有一个形状

{
  questionID: 1,
  questionText:'bla bla bla',
  end: false
}

我还有一个函数,getNextQuestion,它接受 id 并返回一个屏幕

const getNextQuestion = id => R.find(R.propEq(['questionID'], id))(questions);

(当然可以使用Array.find,但我正在探索 Ramda)

我想编写一个生成器,该生成器将从此数组中生成特定对象,由传入的id 选择,直到生成具有end === true 的对象

也就是说,带有这个特定id 的对象应该是生成器返回的last 值。之后生成器应该产生{value: undefined, done: true

我想写这样的东西

export function* questionGenerator() {
  let nextID = 1;
  let continueLoop = true;
  while (continueLoop) {
    const question = getNextQuestion(nextID);
    if (question.end) continueLoop = false;
    nextID = yield getNextQuestion(nextID);
  }
}

会这样调用

const qGen = questionGenerator();
const id = 1;
do {
  const result = gGen.next(i++)
  console.log(result.value)
} while (!result.done)

但我不确定这是否是最好的写法。

有没有更好的办法?

【问题讨论】:

  • 你有运行的例子吗?
  • 我认为,yield 的结果是传递给 next 的值。这实现了生成器和客户端之间的双向通信。这可能会有所帮助。
  • getNextScreen() 真的一次返回一个屏幕,但下一次返回一个 id?
  • 能否提供函数getNextScreen的代码?

标签: javascript ecmascript-6 generator


【解决方案1】:

您需要在生成器中进行一些更改以返回生成器,并在循环中进行另一项更改以调用生成器。

const questions = [{ questionID: 1, questionText:'bla bla bla', end: false }, { questionID: 2, questionText:'bla bla bla', end: false }, { questionID: 3, questionText:'bla bla bla', end: false }, { questionID: 4, questionText:'bla bla bla', end: false }, { questionID: 5, questionText:'bla bla bla', end: true }];

const getNextQuestion = (array => id => array.find(({ questionID }) => questionID === id))(questions);

function* questionGenerator() {
    let nextID = 1;
    while (true) {
        const question = getNextQuestion(nextID);
        nextID = yield question;
        if (question.end) return;
    }
}

const gGen = questionGenerator();

var id = 1;

while (true) {
    const result = gGen.next(id++);
    if (result.done) break;
    console.log(result.value);
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    您可以从生成器中return,这将简化您的代码:

     while (true) {
      const screen = getNextScreen(nextID);
      nextID = yield screen;
      if (screen.end) return;   
     }
    

    【讨论】:

      猜你喜欢
      • 2017-02-22
      • 1970-01-01
      • 2012-04-06
      • 2023-03-17
      • 2021-10-29
      • 2013-03-02
      • 2019-06-11
      • 2011-08-26
      • 2018-06-15
      相关资源
      最近更新 更多