1.什么是生成器
生成器是一个函数,可以用来生成迭代器
生成器函数和普通函数不一样,普通函数是一旦调用一定会执行完
但是生成器函数中间可以暂停,可以执行一会歇一会
生成器函数有一个特点,需要加*
2.生成器有若干个阶段,如何划分这些阶段呢?
function *go(a){
console.log(1);
//此处的b用来供外界输入进来的
//这一行实现输入和输出,本次的输出放在yield后面,下次的输入放在yield前面
let b = yield a;
console.log(2);
let c = yield b;
console.log(3);
return c;
}
//生成器函数和普通的函数不一样,调用它的话函数并不会立刻执行
//它会返回此生成器的迭代器,迭代器是一个对象,每调用一次next就可以返回一个值对象
let it = go("a值");
console.log(it);//{}
//next第一次执行不需要参数,传参数没有意义
let r1 = it.next();
////第一次调用next会返回一个对象,此对象有两个属性,一个是value就是yield后面那个值,一个是done表示是否迭代完成
console.log(r1);//{ value: 'a值', done: false }
let r2 = it.next('B值');
console.log(r2);//{ value: 'B值', done: false }
let r3 = it.next('C值');
console.log(r3);//{ value: 'C值', done: true }
每当调用生成器对象的.next()方法时,函数恢复运行直至遇到下一个yield表达式,其作用是用于迭代。因此it.next()的目的是为了返回不同的字符串。在最后的it.next()中,使用done:true表示结束。到达函数末端意味着返回的结果是undefined,所以代码片段中使用value: undefined结尾。
3.生成器的return的值不会被for...of循环到,也不会被扩展符遍历到
function *gen(){
yield 0;
yield 1;
return 2;
yield 3;
};
let g=gen();
console.log([...g]);//[ 0, 1 ] return 2和yield 3没有生效
4.在一个生成器函数里面调用另外一个生成器函数
function *foo(){
yield 0;
yield 2;
}
function *go(){
yield "x";
yield *foo();
yield "y";
}
let g=go();
console.log([...g]);//[ 'x', 0, 2, 'y' ]
5.模拟下next()返回值结构是
{
value:"value",//value为返回的值
done:false//done的值为一个布尔值,如果迭代器未遍历完毕,它就返回false,否则返回true
}
function gen(arry){
var nextIndex=0;
return {
next:function(){
return nextIndex<arry.length?{value:arry[nextIndex++],done:false}:{value:undefined,done:true};
}
}
}
let arr=["1", "2", "3", "4"];
let it = gen(arr);
console.log(it.next());//{ value: '1', done: false }
console.log(it.next());//{ value: '2', done: false }
console.log(it.next());//{ value: '3', done: false }
console.log(it.next());//{ value: '4', done: false }
console.log(it.next());//{ value: undefined, done: true }
6.next()方法传参数:
function* foo(x) {
let a = 2 * (yield(x + 1));
let b = yield(a / 3);
return (x + a + b);
}
//没传参的情况
var it=foo(5);
console.log(it.next());//{ value: 6, done: false }
console.log(it.next());//{ value: NaN, done: false }
console.log(it.next());//{ value: NaN, done: true }
//传参数的情况:
var it1=foo(5);
//第一次next传参没意义
console.log(it1.next());//{ value: 6, done: false }
console.log(it1.next(6));//{ value: 2, done: false }
console.log(it1.next(7));//{ value: 24, done: true }
7.try catch throw
function *go(){
try{
yield;
}catch(e){
console.log("err",e)
}
}
let it=go();
it.next();
try{
it.throw("出错了");
}catch(e){
console.log("外部捕获",e)
}
//输出的结果是:"err 出错了"