generator生成器
1、基本概念
执行Generator函数会返回一个迭代器对象,也就是说,Generator函数还是一个迭代器对象生成的函数,返回的迭代器对象,可以依次遍历Generator函数内部的每一个状态,生成器也是一个函数
跟普通函数的区别
1、function关键字与函数名之间有一个星号
2、函数体内部使用yield表达式,定义不同的内部状态
3、·Generator·函数不能跟new一起使用,会报错
2、generator的基本使用
(1)定义generator函数
在function关键字和函数名之间加一个*号就表示这是一个generator函数
function * show(){
yield 语句;
yield 语句;
}
(2)generator函数的调用
function * show(){
yield 1;
yield 2;
yield 3;
}
let p=show();
console.log(p);
//generator对象上p有一个next方法,执行后返回一个对象,对象里是一个yield值value属性和done属性为false
console.log(p.next());
console.log(p.next());
console.log(p.next());
//当done属性为true时表示generator里面的内容执行完毕,如果还继续调用next方法,返回值value为undefined
console.log(p.next());

(3)generator函数批量处理yield
注意:yield关键字只能在生成器generator函数中使用,否则会报错
function * show(arr){
for(let i=0;i<arr.length;i++){
yield arr[i];
}
}
let p=show([1,2,3,4]);
console.log(p);
console.log(p.next());

(4)generator函数表达式
除了可以通过函数声明的方式创建生成器的函数,也可以通过函数表达式创建generator生成器
注意:不能通过箭头函数创建生成器
let show=function *(arr){
for(let i=0;i<arr.length;i++){
yield arr[i];
}
}
let p=show([1,2,3,4]);
console.log(p);
console.log(p.next());
(5)generator不同的调用
循环
for...of适合generator循环,但是不会遍历return后面的内容
function * show(){
yield 1;
yield 2;
yield 3;
}
let p=show();
for(let val of p){
console.log(val);
}

解构
function * show(){
yield 1;
yield 2;
yield 3;
}
let p=show();
let [a,b,c]=show();
console.log(a,b,c);

扩展运算符
function * show(){
yield 1;
yield 2;
yield 3;
}
let p=show();
console.log(...p);

Array.from()
function * show(){
yield 1;
yield 2;
yield 3;
}
let p=show();
console.log(Array.from(p));

(6)对象的生成器方法
对象生成器方法
由于生成器本身就是函数,因此可以添加到对象中,成为对象的方法
let obj={
// createIterator:function *(arr){
// for(let i=0;i<arr.length;i++){
// yield arr[i]
// }
// }
//也可用ES6对象方法简写创建生成器
*createIterator(arr){
for(let i=0;i<arr.length;i++){
yield arr[i]
}
}
}
let iterator=obj.createIterator([1,2,3]);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

可迭代对象和for…of循环
具有Symbol.iterator方法的对象,通过这个方法可以创建一个迭代器对象.因此所有通过生成器创建迭代器都是迭代对象, 诸如字符串, 数组,Set,Map ,都默认具有迭代器,
而for...of 循环的本质就是通过每次调用迭代对象的next()方法, 并将迭代器返回的 结果对象中的value属性值存到一个变量中, 循环执行直到结果对象中done属性值为true为止
let arr = [10,20,30]
for(let num of arr){
console.log(num)
}
(7)generator生成器处理异步
function run(generator){
let obj=generator();
console.log('obj',obj);
//执行第一次
let res=obj.next();
console.log('res',res);
//递归调用判断done是否为true执行完毕
function step(){
if(!res.done){
//判断res.done是否为true,是就执行完毕,不是就继续递归调用step函数迭代
res=obj.next();
console.log(res);
step();
}
}
step();
}
run(
//生成一个生成器,传入到run函数generator
function *(){
yield 10;
yield 20;
yield 30;
}
)

处理本地异步程序
//generator处理本地异步程序
function asyncFun(num){
return function(cb){
setTimeout(function(){
cb(num)
},1000)
}
}
// let fn=asyncFun(10);
// fn(function(val){
// console.log(val);
// });
//处理generator函数
function run(generator){
let obj=generator();
console.log('obj',obj);
//执行第一次
let res=obj.next();
console.log('res',res); //{value:f(){};done:false;} value是asyncFun函数return出来的函数
//递归调用判断done是否为true执行完毕
function step(){
//判断res.done是否为true,是就执行完毕,不是就继续递归调用step函数迭代
if(!res.done){
//判断value的值是否为函数
if(typeof res.value=='function'){
res.value(function(val){
console.log(val);
res=obj.next(val);
console.log(res);
step();
})
}
}
}
step();
}
run(
//生成一个生成器,传入到run函数generator
function *(){
let res=yield asyncFun(10);
res=yield asyncFun(res+10);
res=yield asyncFun(res+10);
console.log(res);
}
)

767

被折叠的 条评论
为什么被折叠?



