生成器 Generator

# 生成器 Generator

生成器是一个通过构造函数 Generator 创建得对象。 生成器即是一个迭代器(即内部含有 next 方法),同时又是一个可迭代对象(即具有知名符号 Symbol.iterator)。

# 如何创建生成器

生成器得创建,必须使用生成器函数(Generator Function)

# 如何书写一个生成器函数

  function *method(){}

# 生成器函数内部如何执行

生成器函数内部是为了给生成器得每次迭代提供数据。 每次调用生成器得 next 方法,将导致生成器函数运行到下一个 yield 关键字位置。 yield 是一个关键字,改关键字只能在生成器函数内部使用,表达“产生”一个迭代数据。

一种语法糖,方便我们产生迭代数据

function* method() {
    console.log(1);
    yield 1;
    console.log(2);
    yield 2;
    console.log(3);
}

# 生成器细节

  • 生成器可以有返回值,这个值会作为第一次 done 返回 true 得 value 得值。 只有第一次,后面还是会为 undefined
  • 生成器得next 方法可以传入参数,这个参数会作为 yield 表达式得返回值。
  • 首次调用next 方法传入参数是无效得。
  • 生成器内部可以调用其他生成器。 yield * method() 相当于把代码直接粘贴过来
function* test() {
    console.log('first');
    let info = yield 1;
    console.log('second');
    info = yield info + 2;
    console.log('third');
    info = yield info * 5;
    console.log('end');
    return 'end'
}

var gen = test()
console.log(gen.next()); // 1
console.log(gen.next(5)); // 7
console.log(gen.next(2)); // 10
console.log(gen.next(2)); // end

# 其他 Api

1、 return 方法,提前结束生成器得迭代过程。 2、 throw 方法,在生成器内部抛出异常。

# 生成器异步控制

function call(generatorFunc) {
    let generator = generatorFunc();
    let result = generator.next();

    const handler = () => {
        if (result.done) return;
        // 处理返回值为 Promise 得情况
        if (typeof result.value.then == 'function') {
            result.value.then(data => {
                result = generator.next(data)
                handler(result);
            }).catch(err => {
                generator.throw(err)
            })
        } else {
            // 处理其他情况
            result = generator.next(result.value);
            handler(result);
        }
    }

    handler(result);
}