Как вы завершаете «бесконечный» генератор в JavaScript? - PullRequest
2 голосов
/ 22 апреля 2020

РЕДАКТИРОВАТЬ: я отредактировал, чтобы включить более актуальный код, кажется, мой пример «уменьшенного размера» был немного запутанным.

У меня есть массив javascript, questions неизвестной длины, который содержит объекты, один для каждого «вопроса», каждый из которых имеет форму

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

У меня также есть функция getNextQuestion, которая принимает id и возвращает экран

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

(конечно, можно использовать Array.find для вышеизложенного, но я изучаю Рамду)

Я хочу написать генератор, который выдаст определенный объект из этого массива, выбранный передается в 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)

но я не уверен, что это лучший способ написать это.

Есть ли лучший способ?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Вам нужно внести некоторые изменения в генератор, чтобы вернуть генератор, и еще одно изменение в l oop для вызова генератора.

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; }
1 голос
/ 22 апреля 2020

Вы можете return из генератора, что упростит ваш код:

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