Я попытался настроить это, изменив генератор на обычную функцию. например,
function gennum(){
for( let i=0; i<150; i++) {
return i}}
Это не работает, потому что первый return i
завершает функцию. Вызов функции вернет значение 0
. При повторном вызове вы все равно получите значение 0
.
В чем причина использования этого кода, использующего генератор, а не просто обычную функцию, возвращающий значения и сохраняющий их в массиве или объекте?
В этом конкретном примере c вы можете вернуть массив из всех 150 значений. Так что это не лучший пример генератора.
Несколько ключевых моментов о функциях генератора и генераторах, которые они создают:
Генератор - это полезный способ создания последовательность, которая никогда не заканчивается. Код, использующий генератор, использует значение за раз. Напротив, вы не можете поместить последовательность, которая никогда не заканчивается в массиве.
Генераторы - очень полезный способ написать итераторы, чтобы код, использующий их, мог использовать одно значение в время. Рассмотрим, как вы пропускаете oop через массив. Вы можете l oop через значения генератора (итератора) аналогичным образом (или даже точно так же, через for-of
).
Код функции генератора не должен быть простым l oop, хотя это обычное дело. Он может иметь произвольно сложные logi c, потому что вы можете делать все, что захотите, между yield
s.
Генератор может потреблять значений, заданных для это с помощью кода, использующего его, а не просто , производящего значений, как это делает пример в вашем вопросе. Чтобы получить значения из кода, использующего его, код функции генератора использует значение результата yield
. Чтобы код не использовал логику триггера генератора c в функции генератора.
В комментарии к вопросу, который вы сказали:
, я конкретно задаюсь вопросом: «var gennumcollect = gennum ();» Похоже, что переменная gennumcollect хранит доходность генератора. Я прав? вместо определения переменной, которая является генератором, вместо этого он фактически сохраняет значения.
Нет, он сохраняет генератор, который возвращает функция генератора. Генератор - это объект с методом next
, который дает вам "следующее" значение от генератора, которое функция штрафует.
Когда вы вызываете функцию генератора, он создает и возвращает объект-генератор, который будет ходить через логи c функции. На данный момент в функции еще ничего не запущено. Код в функции генератора запускается только тогда, когда код вызывает next
для получения "следующего" значения от генератора. Рассмотрим этот пример:
function* gennum() {
console.log("gennum: Starting");
for (let i = 0; i < 5; ++i) {
console.log(`gennum: About to yield ${i}`);
yield i;
console.log(`gennum: Back from yield ${i}`);
}
console.log("gennum: Done");
}
console.log("main: About to call `gennum`:");
const gen = gennum();
console.log("main: Starting loop:");
for (const v of gen) {
console.log(`main: Got the value ${v}`);
}
.as-console-wrapper {
max-height: 100% !important;
}
Обратите внимание, что вы не видите gennum: Starting
, пока мы не запустили for-of
l oop в основном скрипте.
Вы также можете вызвать next
вручную, что позволяет вам вводить значения в генератор:
function* gennum() {
console.log("gennum: Starting");
for (let i = 0; i < 5; ++i) {
console.log(`gennum: About to yield ${i}`);
const v = yield i;
console.log(`gennum: Back from yield ${i}, got value ${v}`);
}
console.log("gennum: Done");
}
console.log("main: About to call `gennum`:");
const gen = gennum();
console.log("main: 1st call to `next`:");
let result = gen.next();
console.log(`main: Result: ${JSON.stringify(result)}`);
console.log("main: 2nd call to `next`, passing in A:");
result = gen.next("A");
console.log(`main: Result: ${JSON.stringify(result)}`);
console.log("main: 3rd call to `next`, passing in B:");
result = gen.next("B");
console.log(`main: Result: ${JSON.stringify(result)}`);
.as-console-wrapper {
max-height: 100% !important;
}