首先,调用生成器函数不会运行里面的代码,而是返回一个生成器。对于一个生成器而言,调用 next 方法来开始运行,然后在里面碰到 yield 时暂停里面的运行,而回到 next 调用处继续往下执行;再次调用 next,则回到生成器上次停止的地方继续往下执行,直至碰到 yield 而暂停里面回到外面或执行完毕。
作为可迭代对象使用
上面说到,生成器也是一个可迭代对象,那么,这样就可以使用 for-of 来迭代。
1234567891011121314151617
function*foo(){yield1;yield2;return100;}varit=foo();console.log(it.next());console.log(it.next());console.log(it.next());console.log('=== for of ===');for(varvoffoo()){console.log(v);}
在调用 next 触发生成器运行到下一个 yield 处时,会同时返回迭代结果;下一次调用 next 时,可以传递一个参数进去,而这个值将是 yield 表达式的值。
1234567891011
function*first(){vary=(yield'foo');console.log(1+y);yield'ok';}varit=first();console.log(it.next());// send 3 into the place of the first yield as the pass-in valueconsole.log(it.next(3));console.log(it.next());
function*foo(){try{varx=yield3;console.log(x);x();}catch(err){console.log('Error: '+err);}}varit=foo();it.next();it.next();// catch from the outsidefunction*bar(){varx=yield3;console.log(x);x();}varit2=bar();it2.next();try{it2.next();}catch(err){console.log(err);}
异步
生成器能在 yield 时暂停,next 的时候再继续运行。这样,或许能在碰到异步操作时 yield 来暂停,异步完成后再 next 继续运行,从而解决回调嵌套过深以及带来的理解问题。