es6入门—Generator函数
1. 语法和API一种异步编程解决方案。 执行Generator函数返回一个遍历器对象;里面封装了多个状态;可遍历内部的每一个状态。格式:1.function 与函数名之间加“*”号。2.函数内部使用yield语句定义不同的内部状态。示例://yeild语句暂停执行、return函数执行结束function* test(){yield 'hello';...
1. 语法和API
一种异步编程解决方案。
执行Generator函数返回一个遍历器对象;里面封装了多个状态;可遍历内部的每一个状态。
格式:
1.function 与函数名之间加“*”号。
2.函数内部使用yield语句定义不同的内部状态。
示例:
//yeild语句暂停执行、return函数执行结束
function* test(){
yield 'hello';
yield 'world';
return 'ending';
}
函数只能执行一次return语句,所以return后函数执行结束。
和普通函数调用方式相同,实例对象调用next()方法获取yield语句后的值。yield语句不能用于普通函数
var t = test();
//返回一个对象,包含两个值{value:"",done:""}
t.next(); //{value:"hello",done:false}
t.next(); //{value:"world",done:false}
t.next(); //{value:"ending",done:true}
t.next(); //{value:undefined,done:true}
使用next()可阶段性获取到函数中yield语句后的值,可根据done的值为true确认函数是否执行完毕。
1.yield语句在表达式中时,须放在括号里。
2.用作函数参数或赋值表达式的右边,可以不加括号。
1.表达式
//需要将表达式中获取的值在下一次执行next()传递进去。不然console输出undefined
function* test(){
yield 'hello';
console.log((yield "ds"));
yield 'world';
return 'ending';
}
var t = test();
t.next();
var p = t.next();
t.next(p);
2.函数参数yield语句、赋值表达式的右边
let temp = yield "ii";
任意一个对象的Symbol.iterator方法等于该对象的遍历器对象生成函数。
yield语句没有返回值。
function* test(){
//some code
}
var t = test();
t[Symbol.iterator]() === t
next()方法可传入参数
yield语句不会返回值,总是undefined,则在使用yield语句在赋值表达式的右边时,需要在next()方法传入值。
1.一般的Generator函数第一次使用next()方法不能带有参数,
2.若需要第一次传参,则将Generator函数作为另一个函数的返回值,
function warpper(fn){
return function(...args){
let p = fn(...args);
p.next(); //{value:undefined,done:true}
return p;
}
}
var warpped = warpper(function* (){
console.log(`first args:${yield}`);
return 'DONE';
});
let p = warpped();
p.next('hello'); //{value:'DONE',done:true}
p.next(); //{value:undefined,done:true}
for… of循环可以遍历Generator函数,
不需要调用next()方法,在done值为true时,循环结束
//斐波那契数列
function* fibonacci(){
let [prev,curr] = [0,1];
for(;;){
[prev,curr] = [curr,prev+curr];
yield curr;
}
}
for(let n of fibonacci()){
if(n>1000) break;
console.log(n);
}
//通过Generator函数添加Iterator接口,使得某些无法遍历的数据结构可遍历
function* objectEntries(obj){
let keys = Reflect.ownKeys(obj);
for(let key of keys){
yield [key,obj[key]];
}
}
//1.
let p = {name:'小李',age:'23'};
for(let [key,value] of objectEntries(p)){
console.log(`${key}:${value}`);
}
//2.通过的对象Symbol.iterator属性
p[Symbol.iterator] = objectEntries;
for(let [key,value] of p){
console.log(`${key}:${value}`);
}
Generator函数的throw()方法,可以在函数体外抛出错误,然后在Generator函数体内捕获;和全局的throw命令不同,只能被函数体外的catch语句捕获。
1.如果函数体外的catch语句捕获了错误,就不会继续执行后面的语句
2.如果函数内部没有try{}catch(){},throw()方法抛出的错误会被外部的catch语句捕获,执行终止;但是throw命令抛出的错误则不会影响遍历器状态。
3.一旦Generator函数执行过程中使用throw命令抛出错误,就不会执行下去,终止。
Generator函数的return()方法,可以返回给定的值,并终结Generator函数的遍历。
1.如果Generator函数中有try…finally 代码块,那么return语句会在finally代码块执行完后再执行返回值。
yield* 语句,用来在Generator函数中执行另一个Generator函数。
function* inner(){
yield 'hello';
}
function* outer(){
yield 'open';
inner(); //不会执行
yield inner(); //返回inner()的遍历器
yield* inner(); //返回inner()遍历后的值
yield 'word';
}
1.任何有Iterator接口,就可以使用yield*遍历。
2.被调用的Generator函数中有return 语句时,像调用函数中返回值。
3.Generator函数返回的时遍历器对象,而不是this对象,这样this.x = ‘hello’;不会生效;可使用bind()绑定一个空对象给Generator函数。
2.Generator函数推导
惰性求值
1.状态机
每执行一次函数,改变一次状态,执行不同的处理。
2.协程
可以使用Generator函数交换程序执行的控制权。
3.应用
1.异步操作的同步化表达
2.控制流管理,
3.在对象上部署Iterator接口
4.作为数据结构,可以对任意表达式提供类似数组的接口。
更多推荐
所有评论(0)