Generator 应用
-
异步操作的同步化表达
-
控制流管理
-
部署Iterator接口
-
作为数据结构
Generator简介 generator 可理解成一个状态机,封装了多个内部状态;执行genrator函数会返回一个遍历器对象。
function* hello(){ yield "hello"; yield "js"; return "node"; } var h = hello(); h.next(); h.next(); h.next();
next()参数
function* f() { for(var i=0;true;i++){ var reset = yield i; if(reset){i=-1;} } } var g = f(); g.next(); g.next(); g.next(true); function* foo(x){ var y = 2* (yield (x+1)); var z = yield (y/3); return (x+y+z); } var a = foo(5); a.next(); a.next(); a.next(); var b = foo(5); b.next(); b.next(12); b.next(10);
for...of 循环自动遍历generator函数
function* numbers(){ yield 1; yield 2; return 3; yield 4; } [...numbers()]; Array.from(numbers()); let[x,y] = numbers(); for(let n of numbers()){ console.log(n); } //原生js对象没有遍历接口,无法使用for...of function* objectEntries(obj){ let propKeys = Reflect.ownKeys(obj); for(let propkey of propKeys){ yield [propkey,obj[propkey]]; } } let jane = {f:"Jane",l:"Doe"}; for(let [key,val] of objectEntries(jane)){ console.log(`${key}:${val}`); }
Generator.prototype.throw() and Generator.prototype.return()
-
Generator函数返回的遍历器对象都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。
var g = function* (){ while(true){ yield; console.log('inner catch',e); } }; var i = g(); i.next(); try{ i.throw('a'); i.throw('b'); }catch(e){ console.log('outer catch',e); }
-
return 方法可以返回给定的值,并终结Generator函数的遍历
function* gen(){ yield 1; yield 2; return 7; } var g = gen(); g.next(); g.return('gen'); g.next();
yield*语句 等同于在Generator函数内部部署一个 for...of循环
作为对象属性的Generator函数
let obj = { * myGeneratorMethod(){ } } let obj = { myGeneratorMethod:function* (){ } }
Generator函数的this
function* F(){ yield this.x = 1; yield this.y = 2; } //F 返回的是遍历器对象,而不是this对象 var obj = {}; var f = F.bind(obj)(); f.next(); f.next();
Generator函数推导 惰性求值
let bigGenerator = function* (){ for(let i=0;i<1000;i++){ yield i; } }; let squared = (for(n of bigGenerator()){n*n;}); console.log(squared.next());