|
11 | 11 | 9. [Promises](#promises)
|
12 | 12 | 10. [Maps and Sets](#maps-and-sets)
|
13 | 13 | 11. [Iterables and iterators](#iterables-and-iterators)
|
| 14 | +12. [Generators](#generators) |
14 | 15 |
|
15 | 16 | ## Variable scope
|
16 | 17 |
|
@@ -1147,3 +1148,75 @@ console.log(it.next().value); // 'yo'
|
1147 | 1148 | console.log(it.next().value); // 'ya'
|
1148 | 1149 | console.log(it.next().done); // true
|
1149 | 1150 | ```
|
| 1151 | + |
| 1152 | +## Generators |
| 1153 | +Generators are functions that can be paused and resumed (think cooperative multitasking or coroutines), which enables a variety of applications. |
| 1154 | +### A simple generator |
| 1155 | +The `function*` declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object. |
| 1156 | +``` |
| 1157 | +function* idMaker() { |
| 1158 | + var index = 0; |
| 1159 | + while(true) |
| 1160 | + yield index++; |
| 1161 | +} |
| 1162 | + |
| 1163 | +var gen = idMaker(); // "Generator { }" |
| 1164 | + |
| 1165 | +console.log(gen.next().value); // 0 |
| 1166 | +console.log(gen.next().value); // 1 |
| 1167 | +console.log(gen.next().value); // 2 |
| 1168 | +// ... |
| 1169 | +``` |
| 1170 | +The objects returned by generators are iterable; each `yield` contributes to the sequence of iterated values. Therefore, you can use generators to implement iterables, which can be consumed by various ES6 language mechanisms: `for-of` loop, spread operator (`...`), etc. |
| 1171 | +### Kinds of Generators |
| 1172 | +There are four kinds of generators: |
| 1173 | +1. Generator function declarations: |
| 1174 | +``` |
| 1175 | +function* genFunc() { ··· } |
| 1176 | +const genObj = genFunc(); |
| 1177 | +``` |
| 1178 | +2. Generator function expressions: |
| 1179 | +``` |
| 1180 | +const genFunc = function* () { ··· }; |
| 1181 | +const genObj = genFunc(); |
| 1182 | +``` |
| 1183 | +3. Generator method definitions in object literals: |
| 1184 | +``` |
| 1185 | +const obj = { |
| 1186 | + * generatorMethod() { |
| 1187 | + ··· |
| 1188 | + } |
| 1189 | + }; |
| 1190 | +``` |
| 1191 | +4. Generator method definitions in class definitions (class declarations or class expressions): |
| 1192 | +``` |
| 1193 | +class MyClass { |
| 1194 | + * generatorMethod() { |
| 1195 | + ··· |
| 1196 | + } |
| 1197 | + } |
| 1198 | +``` |
| 1199 | +### Terminate a Generator |
| 1200 | +`return()` performs a return at the location of the `yield` that led to the last suspension of the generator. |
| 1201 | +``` |
| 1202 | +function* genFunc1() { |
| 1203 | + try { |
| 1204 | + console.log('Started'); |
| 1205 | + yield; // (A) |
| 1206 | + } finally { |
| 1207 | + console.log('Exiting'); |
| 1208 | + } |
| 1209 | +} |
| 1210 | +``` |
| 1211 | +In the following interaction, we first use `next()` to start the generator and to proceed until the yield in line A. Then we return from that location via `return()`. |
| 1212 | +``` |
| 1213 | +const genObj1 = genFunc1(); |
| 1214 | + |
| 1215 | +genObj1.next() |
| 1216 | +Started |
| 1217 | +{ value: undefined, done: false } |
| 1218 | + |
| 1219 | +genObj1.return('Result') |
| 1220 | +Exiting |
| 1221 | +{ value: 'Result', done: true } |
| 1222 | +``` |
0 commit comments