生成器

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <script>
            // yield關(guān)鍵字,可以讓代碼在其出現(xiàn)的地方暫停執(zhí)行,它只能在生成器函數(shù)內(nèi)部使用。
            // 第一次調(diào)用,函數(shù)里面 yield之前的代碼不會(huì)執(zhí)行,需要調(diào)next方法,yield之前的代碼才會(huì)執(zhí)行
            // 但是 yield之后的代碼不會(huì)執(zhí)行(yield語(yǔ)句會(huì)執(zhí)行,yield 右邊的會(huì)執(zhí)行,yield x++,下面的不會(huì)而已),需要繼續(xù)next方法才會(huì)執(zhí)行yield之后的代碼
            // next方法 返回一個(gè)對(duì)象 ,value屬性,value屬性的值是當(dāng)前yield語(yǔ)句的結(jié)果
            // done:true/false,是否迭代結(jié)束,true已迭代結(jié)束,繼續(xù)調(diào)next方法,value則返回undefined
            // false則表示未迭代結(jié)束,可以繼續(xù)調(diào)用next()
            // next方法可以接收參數(shù),第一個(gè)next傳遞參數(shù)并不會(huì)被接收,只有從第二個(gè)next開(kāi)始傳遞的參數(shù)才會(huì)被接收
            // 如果一個(gè)生成器函數(shù)中使用return,我們需要得到return的值,
            // 這時(shí)候需要使用next方法返回的對(duì)象的value屬性得到返回的值。
            // 生成器函數(shù)
            // 生成器函數(shù)的語(yǔ)法比較簡(jiǎn)單在普通函數(shù)聲明的時(shí)候在函數(shù)名前面添加一個(gè)*即可,如下所示:
            
            // 場(chǎng)景:判斷是否需要繼續(xù)發(fā)請(qǐng)求,放done為true的時(shí)候停止
            // function *gen(){}


            // 當(dāng)函數(shù)被調(diào)用時(shí)會(huì)返回一個(gè)返回值,但是生成器函數(shù)與普通函數(shù)的返回值有些區(qū)別。
            // 普通函數(shù)如果沒(méi)有使用return返回時(shí),接收到的是undefined,
            // 而生成器函數(shù)不管有沒(méi)有return都返回一個(gè)對(duì)象,這個(gè)對(duì)象被稱(chēng)為迭代器,
            // 我們可以通過(guò)這個(gè)對(duì)象控制迭代器的執(zhí)行。 通常, 使用迭代器的next方法, 讓其繼續(xù)執(zhí)行。

            // let x = 0;

            // function* gen() {
            //  console.log(x);
            //  yield x++;
            // }
            // let itr = gen(); //函數(shù)的里代碼console.log(x);不會(huì)執(zhí)行
            // console.log(itr); //返回一個(gè)gen函數(shù)名對(duì)象
            // itr.next()//函數(shù)的里代碼console.log(x)執(zhí)行了
            // console.log(x);// yield x++; 也執(zhí)行了 1
            //根據(jù)上面的結(jié)果我們可以知道,生成器函數(shù)在被調(diào)用時(shí)并不會(huì)開(kāi)始執(zhí)行代碼,但是得到了一個(gè)對(duì)象,
            //我們讓它繼續(xù)執(zhí)行函數(shù)內(nèi)的代碼,需要調(diào)用next方法。

            // 看看next方法輸出什么
            let x = 0;

            function* gen() {
                console.log(x);
                yield x++;
                console.log("ssssss",x);
                return x;
            }
            let itr = gen();
            let res = itr.next();
            console.log(res); //{value: 1, done: true}
            //next方法也會(huì)返回一個(gè)對(duì)象,這個(gè)對(duì)象包含一個(gè)value屬性,value屬性的值是當(dāng)前yield語(yǔ)句的結(jié)果。
            //則是yield后面 x++ 的結(jié)果;
            //還有one屬性的值表示迭代器的完成狀態(tài),為true表明完成迭代,為false,表明沒(méi)有完成迭代。
            // console.log(res.value);
            res = itr.next();
            console.log(res.value, res);
            res = itr.next();
            console.log(res);
            //如果一個(gè)生成器函數(shù)中使用return,我們需要得到return的值,
            //這時(shí)候需要使用next方法返回的對(duì)象的value屬性得到返回的值。

            // next方法也可以接收一個(gè)值

            // let x = 0;
            // function *gen(){
            //  console.log(yield);
            //   x++;
            //  return x;
            // }
            // let itr = gen();
            // let res = itr.next(6);
            // console.log(res);
            // res = itr.next(7);
            // console.log(res);

            // 根據(jù)結(jié)果我們可以知道, 第一個(gè)next傳遞參數(shù)并不會(huì)被接收, 
            // 規(guī)范和所有兼容瀏覽器都會(huì)默默丟棄傳遞給第一個(gè)next() 的任何東西。 
            // 傳值過(guò)去仍然不是一個(gè)好思路, 因?yàn)槟銊?chuàng)建了沉默的無(wú)效代碼, 這會(huì)讓人迷惑。 
            // 因此, 啟動(dòng)生成器時(shí)一定要用不帶參數(shù)的next()。

            // 只有從第二個(gè)next開(kāi)始傳遞的參數(shù)才會(huì)被接收, 由此, 我們可以總結(jié), 
            // next傳遞的值被上一個(gè)yield接收, next與field相差一個(gè)間隔。

            // 那么為什么會(huì)產(chǎn)生這個(gè)差距呢?

            // 因?yàn)榈谝粋€(gè)next(…) 總是啟動(dòng)一個(gè)生成器, 并運(yùn)行到第一個(gè)yield處。 
            // 不過(guò), 是第二個(gè)next(…) 調(diào)用完成第一個(gè)被暫停的yield表達(dá)式, 第三個(gè)next(…) 調(diào)用完成第二個(gè)yield, 以此類(lèi)推。

            // 以上就是生成器函數(shù)的基本使用, 那么生成器函數(shù)到底有什么用或者說(shuō)能夠應(yīng)用在什么場(chǎng)景呢?

            // 生成器函數(shù)可以應(yīng)用在異步任務(wù)中, 
            // 當(dāng)一個(gè)異步任務(wù)沒(méi)有返回值時(shí)我們可以讓程序在此處暫停當(dāng)有返回值時(shí)在調(diào)用next繼續(xù)執(zhí)行。
            
            // function run(gen) {
            //   var args = [].slice.call(arguments, 1), it;
            
            //   // 在當(dāng)前上下文中初始化生成器
            //   it = gen.apply(this, args);
            
            //   // 返回一個(gè)promise用于生成器完成
            //   return Promise.resolve()
            //     .then(function handleNext(value) {
            //       // 對(duì)下一個(gè)yield出的值運(yùn)行
            //       var next = it.next(value);
            
            //       return (function handleResult(next) {
            //         // 生成器運(yùn)行完畢了嗎?
            //         if (next.done) {
            //           return next.value;
            //         }
            //         // 否則繼續(xù)運(yùn)行
            //         else {
            //           return Promise.resolve(next.value)
            //             .then(
            //               // 成功就恢復(fù)異步循環(huán),把決議的值發(fā)回生成器
            //               handleNext,
            //               // 如果value是被拒絕的promise,
            //               // 就把錯(cuò)誤傳回生成器進(jìn)行出錯(cuò)處理
            //               function handleErr(err) {
            //                 return Promise.resolve(it.throw(err)).then(handleResult);
            //               }
            //             );
            //         }
            //       })(next);
            //     });
            // }

        </script>
    </body>
</html>
?著作權(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)容