Javascript中Generator(生成器函數(shù))淺析

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ò)了"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容