89500297 2020-04-29
// 1. 生成器函数 返回一个迭代器 const generatorFunction = function* () {}; const iterator = generatorFunction(); console.log(iterator[Symbol.iterator]); // function [Symbol.iterator()] // 2. 迭代器什么也不会执行 const generatorFunction = function* () { console.log("a"); }; console.log(1); const iterator = generatorFunction(); console.log(2); // 1 // 2 // 3. next()方法用于推进生成器体的执行: const generatorFunction = function* () { console.log("a"); }; console.log(1); const iterator = generatorFunction(); console.log(2); iterator.next(); console.log(3); // 1 // 2 // a // 3 // 4. next()方法返回一个对象,该对象指示迭代的进展: const generatorFunction = function* () {}; const iterator = generatorFunction(); console.log(iterator.next()); // Object {value: undefined, done: true} // 5. 生成器函数将使用yield关键字。yield暂停生成器的执行,并将控制权返回给迭代器。 const generatorFunction = function* () { yield; }; const iterator = generatorFunction(); console.log(iterator.next()); console.log(iterator.next()); // 6. 挂起时,生成器不会阻塞事件队列: const generatorFunction = function* () { var i = 0; while (true) { yield i++; } }; const iterator = generatorFunction(); console.log(iterator.next); console.log(iterator.next); console.log(iterator.next); console.log(iterator.next); console.log(iterator.next); console.log(iterator.next); // Object {value: 0, done: false} // Object {value: 1, done: false} // Object {value: 2, done: false} // Object {value: 3, done: false} // Object {value: 4, done: false} // Object {value: 5, done: false} // 7. 将一个值传递给迭代器 // 8 yield关键字可以将一个值返回给迭代器: const generatorFunction = function* () { yield "foo"; }; iterator = generatorFunction(); console.log(iterator.next()); console.log(iterator.next()); // Object {value: "foo", done: false} // Object {value: undefined, done: true} // 9. 可以生成任何数据类型,包括函数、数字、数组和对象。当生成器被推进到完成时,返回值被返回。 const generatorFunction = function* () { yield "foo"; return "bar"; }; const iterator = generatorFunction(); console.log(iterator.next()); console.log(iterator.next()); // Object {value: ‘foo‘, done: false} // Object {value: ‘bar}, done: true} // 10. yield关键字可以从迭代器返回一个值: const generatorFunction = function* () { console.log(yield); }; const iterator = generatorFunction(); iterator.next("foo"); iterator.next("bar"); // bar // 第一个foo不要了 值直接被丢弃 一开始在这里卡了一下 不理解 // 现在的理解是这个样子的 // yield会有一个返回值 第一个foo的返回值被第二个bar覆盖了,然后第一个foo就没有位置输出,输出的是bar // 11. 理解执行流程 // 使用for of 迭代 迭代器 let index; const foo = function* () { yield "foo"; yield* bar(); }; const bar = function* () { yield "bar"; yield* barz(); }; const baz = function* () { yield "baz"; }; for (index of foo()) { console.log(index); } // foo // bar // baz // 将生成器函数嵌套在另一个生成器当中执行实际上 与 将目标生成器函数的主体导入目标生成器相同 // 上述代码等同于 let index; const foo = function* () { yield "foo"; yield "bar"; yield "baz"; }; for (index of foo()) { console.log(index); } // foo // bar // baz // 12. 除了使用 next()推进生成器实例之外,您还可以throw()。抛出的任何东西都会传递回生成器的代码,也就是说,它可以在生成器实例内部或外部处理: const generatorFunction = function* () { while (true) { try { yield; } catch (e) { if (e != "a") { throw e; } console.log("Generator caught", e); } } }; const iterator = generatorFunction(); iterator.next(); try { iterator.throw("a"); itrrator.throw("b"); } catch (e) { console.log("Uncaught", e); } // 所有的数据都能够被抛出,包括函数、数字、数组和对象 // 13. 生成器函数解决了什么问题? // 地狱回调 // tonic ^6.0.0 const foo = (name, callback) => { setTimeout(() => { callback(name); }, 100); }; foo("a", (a) => { foo("b", (b) => { foo("c", (c) => { console.log(a, b, c); }); }); }); // a // b // c // 解决方法 // tonic ^6.0.0 (function* () { const a = yield curry(foo, "a"); const b = yield curry(foo, "b"); const c = yield curry(foo, "c"); console.log(a, b, c); }); // 要执行生成器,我们需要一个控制器。控制器需要完成异步请求并返回结果。 const controller = (generator) => { const iterator = generator(); const advancer = (response) => { // Advance the iterator using the response of an asynchronous callback. const state = iterator.next(response); if (!state.done) { // Make the asynchronous function call the advancer. state.value(advancer); } }; advancer(); };