- Notifications
You must be signed in to change notification settings - Fork918
Description
Описание
После прочтения главы учебника проГенераторы мне стала интересна эта тема я и решил уделить чуть больше внимания, чем на остальные темы. И в конечном итоге я нашел одну особенность, которая не была упомянута в данной главе и которую на мой субъективный взгляд стоит добавить.
В главе было рассказано про то, что операторyield
работает в две стороны - при вызове методаnext
у генератора оператор возвращает значение справа, а если в методnext
передать значение, то оно будет передано части слева от оператораyield
.
Так вот, тоже самое работает и при композиции генераторов с использованием оператораyield*
. Когда вложенный генератор завершает свое выполнение, выполнив последнийyield
, он ждет следующего вызоваnext
и уже после исполнение переходит в генератор на уровень выше. Но я заметил, что если прописать после последнегоyield
операторreturn
с каким либо значением, то есть передать его на уровень выше, а во внешнем генераторе прописать что то типаlet data = yield* generator_func()
, то можно принять возвращенное значение.
Пример:
function*f(){yield2;return3;}function*g(){yield1;letdata=yield*f();// тут выполняются некоторые необходимые преобразования значения datayielddata;}letgen=g();gen.next().value;// 1gen.next().value;// 2gen.next().value;// 3
Мотивация
Я считаю, что для глубокого понимания концепции композиции генераторов нужно знать о вышеописанной особенности.
В доказательство могу еще привести такой пример. Я попытался реализовать систему сценариев поведения телеграмм бота через генераторы. Все сообщения от пользователя передавались в уникальный для каждого генератор, а полученные значения из этого генератора передавались как сообщения от бота пользователю. В итоге я пришел к выводу, что нужно как то передавать последнее значениеyield
в генератор уровнем выше. Так и открыл для себя данную особенность композиции генераторов в JavaScript.
Вот пример кода одного из сценариев:
// Пример сценария-генератораexportdefaultfunction*(){letnum1=Number(yield`Введите первое число`);if(isNaN(num1)){returnyield"[1] Извините, это не число. Повторите попытку"}letnum2=Number(yield`Введите второе число`);if(isNaN(num2)){returnyield"[2] Извините, это не число. Повторите попытку"}returnyield`Сумма ваших чисел:${num1+num2}`}
Готовы ли вы принять участие в реализации данного предложения?
Да, я готов(а) принять участие.