generator简单说是一种可以控制函数内部执行状态的函数 funtion* 定义了generator函数的语法 yield定义了函数内部实现不同的状态 demo1 1 2 3 4 5 6 7 function* build(){ yield 'step1'; return 'done'; } var generator = build(); generator.next(); //{value:'step1',done:false} generator.next(); //{value:'done',done:true}
这里前者是函数体yield后面的值,后者代表函数是否完成 加入函数体内不包含任意一个yield,则函数只是一个延迟执行的函数而已 1 2 generator.next(); //{value:done,done:true} generator.next(); //{value:undefined,done:true}
yield表达式还可以返回值在下一个next里调用,返回值只能通过next函数传参进来 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function* build(){ yield 'step1'; var step = yield 'step2'; if(step == 3){ yield 'step3'; }else{ yield 'step4'; } yield 'step5'; return '执行完毕!'; } var generator = build(); console.log(generator.next(3)); // => {value: 'step1', done: false} console.log(generator.next(3)); // => {value: 'step2', done: false} console.log(generator.next(3)); // => {value: 'step3', done: false} console.log(generator.next(3)); // => {value: 'step5', done: false} console.log(generator.next(3)); // => {value: '执行完毕', done: true}
注意: next传递的参数值是传递给上一次yield表达式,所以上面例子里第三次调用next传递参数其实是把值传递给第二个yield表达式 异常处理 1 2 3 4 5 6 7 8 9 10 function* build(){ try{ throw new Error('from build'); yield 'haha'; }catch(err){ console.log('inside error'+ err); } } var it = build(); it.next() // => inside error: Error: from build!
上面的例子就是在generator里面增加try…catch语句来捕获函数内部的异常,然后generator本身也提供了一个方法用于向外抛出异常 throw 此方法可以向外抛出异常,由外部的try…catch来捕获 1 2 3 4 5 6 7 8 9 10 11 12 13 function * build(){ try{ yield 'haha'; //没有抛出异常 }catch(err){ console.log('inside error: ' + err); } } var it = build(); //外部的try...catch进行捕获 try{ it.throw('from it'); }catch(err){ console.log('out error: ' + err); // => out error from it }
yield* 后面跟上别的generator实例就可以遍历别的generator里的yield了 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function* build(){ var a = yield 1; var b = yield 2; var c = yield* child(); console.log(a, b, c); } function* child(){ var x = yield 3; var y = yield 4; console.log(x, y); return 'child'; } var it = build(); it.next(); it.next('a'); it.next('b'); it.next('c'); it.next('d'); // => c d // => a b child