update modules
This commit is contained in:
62
docs/javascript/09-generators/01-generators.md
Normal file
62
docs/javascript/09-generators/01-generators.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Генераторы
|
||||
|
||||
Обычные функции возвращают только одно-единственное значение (или ничего).
|
||||
|
||||
Генераторы могут порождать (yield) множество значений одно за другим, по мере необходимости. Генераторы отлично работают с перебираемыми объектами и позволяют легко создавать потоки данных.
|
||||
|
||||
- Генераторы создаются при помощи функций-генераторов function* f(…) \{…}.
|
||||
- Внутри генераторов и только внутри них существует оператор yield.
|
||||
- Внешний код и генератор обмениваются промежуточными результатами посредством вызовов next/yield.
|
||||
|
||||
В современном JavaScript генераторы используются редко. Но иногда они оказываются полезными, потому что способность функции обмениваться данными с вызывающим кодом во время выполнения совершенно уникальна. И, конечно, для создания перебираемых объектов.
|
||||
|
||||
## Функция-генератор
|
||||
Источник: [https://learn.javascript.ru/generators](https://learn.javascript.ru/generators)
|
||||
Для объявления генератора используется специальная синтаксическая конструкция: function*, которая называется «функция-генератор».
|
||||
|
||||
Основным методом генератора является next(). При вызове он запускает выполнение кода до ближайшей инструкции yield <значение> (значение может отсутствовать, в этом случае оно предполагается равным undefined). По достижении yield выполнение функции приостанавливается, а соответствующее значение – возвращается во внешний код:
|
||||
|
||||
Результатом метода next() всегда является объект с двумя свойствами:
|
||||
- value: значение из yield.
|
||||
- done: true, если выполнение функции завершено, иначе false.
|
||||
```js
|
||||
function* generateSequence() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
return 3;
|
||||
}
|
||||
let generator = generateSequence();
|
||||
let one = generator.next();
|
||||
alert(JSON.stringify(one)); // {value: 1, done: false}
|
||||
```
|
||||
|
||||
💥 **function\* f(…) или function \*f(…)**
|
||||
|
||||
Нет разницы, оба синтаксиса корректны.\
|
||||
Но обычно предпочтителен первый вариант, так как звёздочка относится к типу объявляемой сущности (function* – «функция-генератор»), а не к её названию, так что резонно расположить её у слова function.
|
||||
|
||||
## Перебор генераторов
|
||||
Как вы, наверное, уже догадались по наличию метода next(), генераторы являются перебираемыми объектами.
|
||||
|
||||
Возвращаемые ими значения можно перебирать через for..of
|
||||
Это из-за того, что перебор через for..of игнорирует последнее значение, при котором done: true. Поэтому, если мы хотим, чтобы были все значения при переборе через for..of, то надо возвращать их через yield:
|
||||
```js
|
||||
function* generateSequence() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
}
|
||||
let generator = generateSequence();
|
||||
for(let value of generator) {
|
||||
alert(value); // 1, затем 2, затем 3
|
||||
}
|
||||
```
|
||||
|
||||
## yield – дорога в обе стороны
|
||||
`yield` – дорога в обе стороны: он не только возвращает результат наружу, но и может передавать значение извне в генератор.
|
||||
|
||||
Чтобы это сделать, нам нужно вызвать `generator.next(arg)` с аргументом. Этот аргумент становится результатом `yield`.
|
||||
Reference in New Issue
Block a user