参考文档
生成器 生成器函数在执行时能暂停,后面又能从暂停处继续执行。
JavaScript 中的生成器和 Promise 结合使用是进行异步编程的强大工具,因为它们减轻了诸如回调地狱和控制反转的问题。然而对于这些问题可以通过 async 函数实现更简单的坚决方案 。
调用一个生成器函数并不会马上执行它的主体,而是返回一个这个生成器对象。当迭代器 next()
方法被调用时,生成器函数的主体会执行到首个 yield
表达式处,该表达式制定了要从迭代器返回的值,或使用 yield*
委托给其他生成器函数。next()
方法返回一个包含 value
和 done
属性的对象。调用带参数的 next()
方法将恢复生成器函数的执行,用 next()
中的参数替换暂停执行的 yield
表达式。
生成器中的 return
语句执行时意味着生成器结束(done
属性设置为 true
)。如果返回一个值,它将被设置为生成器返回的 value
属性。与 return
语句非常类似,在生成器内部抛出的错误将使生成器结束,除非在生成器主体中完成 catch。一个生成器结束时,后续的 next()
调用将不会执行该生成器的任何代码,只会返回一个这样的对象 {value: undefined, done: true}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function * idMaker ( ) { let index = 0 ; while (true ) { yield index++; } } const gen = idMaker();console .log(gen.next().value); console .log(gen.next().value); console .log(gen.next().value); console .log(gen.next().value);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function * anotherGenerator (i ) { yield i + 1 ; yield i + 2 ; yield i + 3 ; } function * generator (i ) { yield i; yield * anotherGenerator(i); yield i + 10 ; } const gen = generator(10 );console .log(gen.next().value); console .log(gen.next().value); console .log(gen.next().value); console .log(gen.next().value); console .log(gen.next().value);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function * logGenerator ( ) { console .log(0 ); console .log(1 , yield ); console .log(2 , yield ); console .log(3 , yield ); } const gen = logGenerator();gen.next(); gen.next('pretzel' ); gen.next('california' ); gen.next('mayonnaise' );
1 2 3 4 5 6 7 8 9 10 11 // 返回值 function * yieldAndReturn () { yield "Y" ; return "R" ; yield "unreachable" ; } const gen = yieldAndReturn(); console.log (gen.next ()); // { value: "Y" , done: false } console.log (gen.next ()); // { value: "R" , done: true } console.log (gen.next ()); // { value: undefined, done: true }
1 2 3 4 5 6 7 8 9 10 11 12 13 // 作为对象属性的生成器 const someObj = { *generator () { yield 'a' ; yield 'b' ; } } const gen = someObj.generator() console.log (gen.next ()); // { value: 'a' , done: false } console.log (gen.next ()); // { value: 'b' , done: false } console.log (gen.next ()); // { value: undefined, done: true }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 作为对象方法的生成器 class Foo { *generator() { yield 1 ; yield 2 ; yield 3 ; } } const f = new Foo(); const gen = f.generator(); console.log(gen.next()); // { value: 1 , done: false } console.log(gen.next()); // { value: 2 , done: false } console.log(gen.next()); // { value: 3 , done: false } console.log(gen.next()); // { value: undefined, done: true }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 作为计算属性的生成器 class Foo { *[Symbol.iterator ]( ) { yield 1; yield 2; } } const SomeObj = { *[Symbol.iterator ]( ) { yield 'a'; yield 'b'; } } console.log(Array.from(new Foo)); // [ 1, 2 ] console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
1 2 3 function * f ( ) {}const obj = new f;