Выход Javascript из функции, вложенной внутри генератора
Этот код генерирует ошибку:
function *giveNumbers() {
[1, 2, 3].forEach(function(item) {
yield item;
})
}
Это, вероятно, потому, что выход внутри функции, которая не является генератором. Есть ли элегантный способ преодолеть это? Я имею в виду, кроме:
function *giveNumbers() {
let list = [1, 2, 3];
for (let i = 0; i < list.length; i++) {
yield list[i];
}
}
Ответы
Ответ 1
Это, вероятно, потому, что выход внутри функции, которая не является генератором.
Да. Вы не можете использовать yield
от обратных вызовов.
Есть ли элегантный способ преодолеть это?
Зависит от варианта использования. Обычно существует нулевая причина, по которой на самом деле нужно получить yield
от обратного вызова.
В вашем случае вы хотите, чтобы for…of
цикла, который превосходит .forEach
почти в каждом аспекте:
function *giveNumbers() {
for (let item of [1, 2, 3])
yield item;
}
Ответ 2
yield возвращает результат вызывающему.
допустим, что обратный вызов forEach
является генератором (это не проблема для установки там генератора костюмов) - это означает, что когда обратный вызов yield
результат, он возвращает его обратно для forEach
.
В принципе, в вашем вопросе, что вы можете сделать, это:
callback -> yields to forEach -> yields to giveNumbers -> yields to caller
Итак, forEach
должен вернуть результат, чтобы giveNumbers
. но поскольку forEach
не работает так, это невозможно без повторных прототипов массивов с костюмом forEach
.
На самом деле, второй фрагмент является самым элегантным для начала.
Ответ 3
вы можете использовать синтаксис yield *
.
function *giveNumbers() {
yield * [1, 2, 3].map(function(item) {
return item;
})
}
Ответ 4
Вы также можете использовать аргументы while
и pass как таковые (Demo)
function *giveNumbers(array, start) {
var index = start || 0;
while(array.length > index + 1) {
yield array[index++];
}
return array[index];
}
var g = giveNumbers([1,2,3], 0);
var finished = false;
while(!finished) {
var next = g.next();
console.log(next.value);
if(next.done) {
finished = true;
}
}