2024-05-06 20:40:05 +00:00
|
|
|
---
|
2024-10-30 17:34:11 +00:00
|
|
|
date: 2020-09-11
|
2024-05-06 20:40:05 +00:00
|
|
|
id: b2b11ef2-898f-45c7-ad25-967ac7bc9d8b
|
|
|
|
title: JavaScript Generators
|
|
|
|
---
|
|
|
|
|
|
|
|
# ES6
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
|
|
|
|
Generators are processes that you can pause and resume. Generators are
|
|
|
|
defined with `function*`.
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
const foo = function* () {
|
|
|
|
yield 'a';
|
|
|
|
yield 'b';
|
|
|
|
yield 'c';
|
|
|
|
};
|
|
|
|
|
|
|
|
let str = '';
|
|
|
|
for (const val of foo()) {
|
|
|
|
str = str + val;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(str);
|
|
|
|
```
|
|
|
|
|
|
|
|
## Generator Kinds
|
|
|
|
|
|
|
|
### Generator function declarations
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
function* genFunc() { }
|
|
|
|
const genObj = genFunc();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Generator function expressions
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
const genFunc = function* () { };
|
|
|
|
const genObj = genFunc();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Generator method definitions in object literals
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
const obj = {
|
|
|
|
* generatorMethod() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const genObj = obj.generatorMethod();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Generator method definitions in class definitions
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
class MyClass {
|
|
|
|
* generatorMethod() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const myInst = new MyClass();
|
|
|
|
const genObj = myInst.generatorMethod();
|
|
|
|
```
|
|
|
|
|
|
|
|
# Examples
|
|
|
|
|
|
|
|
## Iterables
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
function* objectEntries(obj) {
|
|
|
|
const propKeys = Reflect.ownKeys(obj);
|
|
|
|
|
|
|
|
for (const propKey of propKeys) {
|
|
|
|
// `yield` returns a value and then pauses
|
|
|
|
// the generator. Later, execution continues
|
|
|
|
// where it was previously paused.
|
|
|
|
yield [propKey, obj[propKey]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const jane = { first: 'Jane', last: 'Doe' };
|
|
|
|
for (const [key,value] of objectEntries(jane)) {
|
|
|
|
console.log(`${key}: ${value}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Output:
|
|
|
|
// first: Jane
|
|
|
|
// last: Doe
|
|
|
|
```
|
|
|
|
|
|
|
|
## Async Iterables
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
async function* createAsyncIterable(syncIterable) {
|
|
|
|
for (const elem of syncIterable) {
|
|
|
|
yield elem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Asynchronous code
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
const fetchJson = co.wrap(function* (url) {
|
|
|
|
try {
|
|
|
|
let request = yield fetch(url);
|
|
|
|
let text = yield request.text();
|
|
|
|
return JSON.parse(text);
|
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
console.log(`ERROR: ${error.stack}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
fetchJson('http://example.com/some_file.json')
|
|
|
|
.then(obj => console.log(obj));
|
|
|
|
```
|
|
|
|
|
|
|
|
# Also see
|
|
|
|
|
|
|
|
- [Iterables](20201014092625-javascript_iterables)
|
|
|
|
- [Promises](20200911154351-promises)
|