wiki/content/20200911155947-generators.md

2.1 KiB

date id title
20200911 b2b11ef2-898f-45c7-ad25-967ac7bc9d8b JavaScript Generators

ES6

Introduction

Generators are processes that you can pause and resume. Generators are defined with function*.

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

function* genFunc() { }
const genObj = genFunc();

Generator function expressions

const genFunc = function* () { };
const genObj = genFunc();

Generator method definitions in object literals

const obj = {
    * generatorMethod() {
    }
};
const genObj = obj.generatorMethod();

Generator method definitions in class definitions

class MyClass {
    * generatorMethod() {
    }
}
const myInst = new MyClass();
const genObj = myInst.generatorMethod();

Examples

Iterables

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

async function* createAsyncIterable(syncIterable) {
  for (const elem of syncIterable) {
    yield elem;
  }
}

Asynchronous code

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