1.什么是生成器
生成器是一個(gè)函數(shù),可以用來(lái)生成迭代器
生成器函數(shù)和普通函數(shù)不一樣,普通函數(shù)是一旦調(diào)用一定會(huì)執(zhí)行完
但是生成器函數(shù)中間可以暫停,可以執(zhí)行一會(huì)歇一會(huì)
生成器函數(shù)有一個(gè)特點(diǎn),需要加*
2.生成器有若干個(gè)階段,如何劃分這些階段呢?
function *go(a){
console.log(1);
//此處的b用來(lái)供外界輸入進(jìn)來(lái)的
//這一行實(shí)現(xiàn)輸入和輸出,本次的輸出放在yield后面,下次的輸入放在yield前面
let b = yield a;
console.log(2);
let c = yield b;
console.log(3);
return c;
}
//生成器函數(shù)和普通的函數(shù)不一樣,調(diào)用它的話函數(shù)并不會(huì)立刻執(zhí)行
//它會(huì)返回此生成器的迭代器,迭代器是一個(gè)對(duì)象,每調(diào)用一次next就可以返回一個(gè)值對(duì)象
let it = go("a值");
console.log(it);//{}
//next第一次執(zhí)行不需要參數(shù),傳參數(shù)沒(méi)有意義
let r1 = it.next();
////第一次調(diào)用next會(huì)返回一個(gè)對(duì)象,此對(duì)象有兩個(gè)屬性,一個(gè)是value就是yield后面那個(gè)值,一個(gè)是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 }
每當(dāng)調(diào)用生成器對(duì)象的.next()方法時(shí),函數(shù)恢復(fù)運(yùn)行直至遇到下一個(gè)yield表達(dá)式,其作用是用于迭代。因此it.next()的目的是為了返回不同的字符串。在最后的it.next()中,使用done:true表示結(jié)束。到達(dá)函數(shù)末端意味著返回的結(jié)果是undefined,所以代碼片段中使用value: undefined結(jié)尾。
3.生成器的return的值不會(huì)被for...of循環(huán)到,也不會(huì)被擴(kuò)展符遍歷到
function *gen(){
yield 0;
yield 1;
return 2;
yield 3;
};
let g=gen();
console.log([...g]);//[ 0, 1 ] return 2和yield 3沒(méi)有生效
4.在一個(gè)生成器函數(shù)里面調(diào)用另外一個(gè)生成器函數(shù)
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()返回值結(jié)構(gòu)是
{
value:"value",//value為返回的值
done:false//done的值為一個(gè)布爾值,如果迭代器未遍歷完畢,它就返回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()方法傳參數(shù):
function* foo(x) {
let a = 2 * (yield(x + 1));
let b = yield(a / 3);
return (x + a + b);
}
//沒(méi)傳參的情況
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 }
//傳參數(shù)的情況:
var it1=foo(5);
//第一次next傳參沒(méi)意義
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("出錯(cuò)了");
}catch(e){
console.log("外部捕獲",e)
}
//輸出的結(jié)果是:"err 出錯(cuò)了"