<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      迭代、迭代器、生成器的前世今生

      什么是迭代

      類似于遍歷 遍歷:有多個(gè)數(shù)據(jù)組成的集合數(shù)據(jù)結(jié)構(gòu)(map、set、array等其他類數(shù)組),需要從該結(jié)構(gòu)中依次取出數(shù)據(jù)進(jìn)行某種處理。 迭代:按照某種邏輯,依次取出下一個(gè)數(shù)據(jù)進(jìn)行處理。

      什么是迭代器 iterator

      JS語(yǔ)言規(guī)定,如果一個(gè)對(duì)象具有next方法,并且next方法滿足一定的約束,則該對(duì)象是一個(gè)迭代器(iterator)。 next方法的約束:該方法必須返回一個(gè)對(duì)象,該對(duì)象至少具有兩個(gè)屬性:

      • value:any類型,下一個(gè)數(shù)據(jù)的值,如果done屬性為true,通常,會(huì)將value設(shè)置為undefined
      • done:bool類型,是否已經(jīng)迭代完成
      • 通過迭代器的next方法,可以依次取出數(shù)據(jù),并可以根據(jù)返回的done屬性,判定是否迭代結(jié)束。

      案例如下:

      /**
             * 迭代器
             * 必須有個(gè)next函數(shù)
             * 該函數(shù)必須返回一個(gè)對(duì)象 包括 value 屬性 和 done屬性
             * value:本次迭代的返回值
             * done:true 或者 false 本次迭代是否結(jié)束
             * */
            const iterator = {
              total:3,
              index:1,
              next(){
                const obj = {
                  value:this.index > this.total?undefined:Math.random(),
                  done:this.index > this.total
                }
                this.index++;
                return obj;
              }
            }
      
            //一個(gè)一個(gè)迭代直到不能迭代為止
      
            let result = iterator.next();
            while(!result.done){
              console.log(result);
              result = iterator.next();
            }
      
            //輸出斐波拉數(shù)列的數(shù)據(jù)
            //1 1 2 3 5 8 13 21
            const sequenceItereator = {
              a:1,
              b:1,
              curIndex:1, //當(dāng)前從1開始算
              next(){
                if(this.curIndex == 1 || this.curIndex == 2){
                  this.curIndex++;
                  return {
                    value:1,
                    done:false
                  }
                }
                var c = this.a + this.b;
                this.curIndex++;
                this.a = this.b;
                this.b = c;
                return {
                  value:c,
                  done:false
                }
              }
            }
      
            for(var i = 0;i<50;i++){
              console.log(sequenceItereator.next());
            }

       

      什么是迭代器創(chuàng)建函數(shù)

      它是指一個(gè)函數(shù),調(diào)用該函數(shù)后,返回一個(gè)迭代器,則該函數(shù)稱之為迭代器創(chuàng)建函數(shù),可以簡(jiǎn)稱位迭代器函數(shù)。

      案例如下:

      //迭代器創(chuàng)建函數(shù)
            function createIterator(arr){
              var i = 0;
              return {
                next(){
                  var obj = {
                    value:arr[i],
                    done:i>arr.length - 1
                  }
                  i++;
                  return obj;
                }
              }
            }
            var iterator = createIterator([1,3,5,7,9]);
            console.log(iterator);

       

      什么是可迭代協(xié)議

      ES6中出現(xiàn)了for-of循環(huán),該循環(huán)就是用于迭代某個(gè)對(duì)象的,因此,for-of循環(huán)要求對(duì)象必須是可迭代的(對(duì)象必須滿足可迭代協(xié)議) 可迭代協(xié)議是用于約束一個(gè)對(duì)象的,如果一個(gè)對(duì)象滿足下面的規(guī)范,則該對(duì)象滿足可迭代協(xié)議,也稱之為該對(duì)象是可以被迭代的。 可迭代協(xié)議的約束如下:

      • 對(duì)象必須有一個(gè)知名符號(hào)屬性(Symbol.iterator)
      • done:bool類型,是否已經(jīng)迭代完成
      • 該屬性必須是一個(gè)無參的迭代器創(chuàng)建函數(shù)

      案例如下:

      //可迭代協(xié)議
            var robj = {
              [Symbol.iterator]:function(){
                var total = 3;
                var i = 1;
                return {
                  next(){
                    var oop = {
                      value:i>total?undefined:Math.random(),
                      done:i>total
                    }
                    i++;
                    return oop;
                  }
                }
              }
            };
            for (const element of robj) {
              console.log(element);
            }

       

      什么是生成器

      生成器:由構(gòu)造函數(shù)Generator創(chuàng)建的對(duì)象,該對(duì)象既是一個(gè)迭代器,同時(shí),又是一個(gè)可迭代對(duì)象(滿足可迭代協(xié)議的對(duì)象)

      **注意:Generator構(gòu)造函數(shù),不提供給開發(fā)者使用,僅作為JS引擎內(nèi)部使用**

      生成器函數(shù)(生成器創(chuàng)建函數(shù)):該函數(shù)用于創(chuàng)建一個(gè)生成器。

      ES6新增了一個(gè)特殊的函數(shù),叫做生成器函數(shù),只要在函數(shù)名與function關(guān)鍵字之間加上一個(gè)*號(hào),則該函數(shù)會(huì)自動(dòng)返回一個(gè)生成器

      生成器函數(shù)的特點(diǎn):

      • 調(diào)用生成器函數(shù),會(huì)返回一個(gè)生成器,而不是執(zhí)行函數(shù)體(因?yàn)椋善骱瘮?shù)的函數(shù)體執(zhí)行,收到生成器控制)
      • 每當(dāng)調(diào)用了生成器的next方法,生成器的函數(shù)體會(huì)從上一次yield的位置(或開始位置)運(yùn)行到下一個(gè)yield
        • yield關(guān)鍵字只能在生成器內(nèi)部使用,不可以在普通函數(shù)內(nèi)部使用
        • 它表示暫停,并返回一個(gè)當(dāng)前迭代的數(shù)據(jù)
        • 如果沒有下一個(gè)yield,到了函數(shù)結(jié)束,則生成器的next方法得到的結(jié)果中的done為true
      • yield關(guān)鍵字后面的表達(dá)式返回的數(shù)據(jù),會(huì)作為當(dāng)前迭代的數(shù)據(jù)
      • 生成器函數(shù)的返回值會(huì)作最終的value的值 但是當(dāng)在進(jìn)行next時(shí) value是undefined
      • 生成器在調(diào)用next的時(shí)候可以傳遞參數(shù),該參數(shù)會(huì)作為上一次yield整個(gè)表達(dá)式的返回結(jié)果

      案列如下:

      //生成器函數(shù)  調(diào)用該函數(shù)返回一個(gè)生成器  該生成器即使是一個(gè)迭代器 又是一個(gè)可迭代對(duì)象(滿足可迭代協(xié)議)
            function* createGenerator(){
              console.log('函數(shù)體執(zhí)行 - 開始');
              yield 1; //會(huì)作為本次迭代的value值 {value:1,done:false}
              console.log("函數(shù)體執(zhí)行 - 1")
              yield 2;//會(huì)作為本次迭代的value值 {value:2,done:false}
              console.log('函數(shù)體執(zhí)行 - 2');
              yield 3;//會(huì)作為本次迭代的value值 {value:3,done:false}
              console.log("函數(shù)體執(zhí)行 - 3");
              return "結(jié)束"//會(huì)作為本次迭代的value值 {value:"結(jié)束",done:true}
            }
            //掉用只會(huì)返回一個(gè)生成器 不會(huì)執(zhí)行函數(shù)體
            var generator = createGenerator();
            //當(dāng)調(diào)用next的時(shí)候會(huì)從開始位置到第一個(gè)yield處執(zhí)行  執(zhí)行到y(tǒng)ield位置就會(huì)卡住(不會(huì)繼續(xù)執(zhí)行), 等到下一次next的時(shí)候
            //生成器的函數(shù)體會(huì)從上一次yield的位置(或開始位置)運(yùn)行到下一個(gè)yield
            console.log(generator.next);
            const iterator = generator[Symbol.iterator]();
      
      
            function* createArrayIterator(array){
              for (let index = 0; index < array.length; index++) {
                const item = array[index];
                console.log(`第${index}次迭代`);
                yield item;
              }
            }
            const arrayIterator = createArrayIterator([1,2,3,4,5,6]);
      //生成器函數(shù)  調(diào)用該函數(shù)返回一個(gè)生成器  該生成器即使是一個(gè)迭代器 又是一個(gè)可迭代對(duì)象(滿足可迭代協(xié)議)
            function* createGenerator(){
              console.log('函數(shù)體執(zhí)行 - 開始');
              let result = yield 1; //會(huì)作為本次迭代的value值 {value:1,done:false}
              console.log("函數(shù)體執(zhí)行 - 1",result)
              result = yield 2;//會(huì)作為本次迭代的value值 {value:2,done:false}
              console.log('函數(shù)體執(zhí)行 - 2',result);
              result = yield 3;//會(huì)作為本次迭代的value值 {value:3,done:false}
              console.log("函數(shù)體執(zhí)行 - 3",result);
              return "結(jié)束"//會(huì)作為本次迭代的value值 {value:"結(jié)束",done:true}
            }
            let itereator = createGenerator();
            let res = itereator.next();
            function run(){
              if(!res.done){
                //如果在調(diào)用next的時(shí)候 給 next傳遞參數(shù)  該參數(shù)會(huì)作為 yield 整個(gè)表達(dá)式的值返回
                //執(zhí)行步驟
                //第一次調(diào)用就不care了  第一次調(diào)用碰到y(tǒng)ield 1; 就會(huì)卡住不會(huì)往下執(zhí)行  這個(gè)時(shí)候還不執(zhí)行賦值操作
                //第二次調(diào)用next 傳遞上一次迭代的值作為參數(shù)傳遞  這個(gè)時(shí)候 就會(huì)從上一次 yield的位置 運(yùn)行到下一個(gè)yield (這個(gè)時(shí)候就會(huì)進(jìn)行賦值操作)
                //整個(gè)yield 表達(dá)式的返回值 就是給next函數(shù)傳遞的參數(shù)
                //依次類推
                console.log(res);
                res = itereator.next("張三:"+Math.random());
                run();
              }
            }
            run();
      var i = 0;
            function asyncData(){
              return new Promise((resolve,reject)=>{
                setTimeout(() => {
                  i++;
                  //3秒后完成 完成的數(shù)據(jù)
                  resolve('完成'+i);
                }, 10000);
              })
            }
            //調(diào)用next()方法時(shí)傳入的值會(huì)作為上一個(gè)yield表達(dá)式的返回值
            //創(chuàng)建一個(gè)生成器函數(shù) 調(diào)用時(shí)返回一個(gè)生成器
            function* task(){
              console.log("開始獲取數(shù)據(jù)");
              let data = yield asyncData();
              console.log('獲取到的數(shù)據(jù)',data);
              data = yield asyncData();
              console.log("又獲取到了數(shù)據(jù)",data);
              data = yield 1;
              console.log('又獲取到了數(shù)據(jù)',data);
              return '結(jié)束';
            }
            //沒封裝之前的寫法
            /*function run(createGenerator){
              const generator = createGenerator();
              let res = generator.next();
              function next(){
                if(!res.done){
                  console.log(res);
                  const value = res.value;
                  if(typeof value.then === 'function'){
                    value.then((data)=>{
                      res = generator.next(data);
                      next();
                    });
                  }else{
                    res = generator.next(value);
                    next();
                  }
                }
              }
              next();
            }*/
      
            //封裝后的寫法
            function run(createGenerator){
              const generator = createGenerator();
              console.log(generator);
              next();
      
              function next(nextValue){
                const res = generator.next(nextValue);
                if(res.done){
                  console.log('生成器迭代結(jié)束');
                  return;
                }
                const value = res.value;
                if(typeof value.then === 'function'){
                  //如果返回的是promise  將promise完成時(shí)的數(shù)據(jù)作為參數(shù)
                  //作為上一次yield表達(dá)式的返回值
                  value.then((data)=>{
                    return next(data)
                  })
                }else{
                  console.log('走這里了')
                  //將上一次迭代獲取到的value的值作為參數(shù) 傳遞給上一次yield表達(dá)式的返回值
                  next(res.value);
                }
              }
            }
      
            run(task);
      function* g2(){
              console.log('g2函數(shù)體-運(yùn)行');
              let res = yield 'g1';
              console.log('g1運(yùn)行');
              res = yield 'g2';
              console.log('g2運(yùn)行')
              return 123;
            }
      
            function* createGenerator(){
                console.log('函數(shù)體-開始')
                let res = yield 1; //1作為 本次迭代的值 {value:1,done:false}
                console.log('函數(shù)體-運(yùn)行1',res);
                res = yield* g2();
                console.log('函數(shù)體-g2',res);
                res = yield 2;
                console.log('函數(shù)體-運(yùn)行2',res);
                res = yield 3;
                console.log('函數(shù)體-運(yùn)行3',res);
                return '結(jié)束'
            }
            var generator = createGenerator();

       

       

      總結(jié):

      生成器的核心價(jià)值在于其?延遲執(zhí)行與狀態(tài)保持能力?,適用于:

      • 需要按需生成數(shù)據(jù)的迭代場(chǎng)景(如分頁(yè)、樹遍歷)
      • 資源敏感型任務(wù)(如大文件處理、流式傳輸)
      • 復(fù)雜流程控制(如多步驟交互、狀態(tài)機(jī))
      • 盡管 async/await 更常用于異步編程,但生成器在定制化迭代器協(xié)議、性能優(yōu)化框架中仍不可替代
      posted @ 2025-05-23 14:03  飛奔的龜龜  閱讀(290)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 四虎成人精品在永久免费| 亚洲综合av男人的天堂| 97久久精品无码一区二区天美| 亚洲码和欧洲码一二三四| 翁源县| 久久亚洲精品中文字幕馆| 国产精品自拍中文字幕| 国产精品普通话国语对白露脸| 浴室人妻的情欲hd三级国产| 青青青国产在线观看免费| 无码专区 人妻系列 在线| 久久久亚洲欧洲日产国码αv| 亚洲AV无码精品色午夜果冻| 亚洲av免费看一区二区| 国产在线中文字幕精品| 国产精品久久久久aaaa| 国产欧美日韩综合精品二区| 国产精品国产高清国产一区| 成人午夜av在线播放| AV最新高清无码专区| 色呦呦九九七七国产精品| 美女胸18下看禁止免费视频| 国产亚洲欧洲av综合一区二区三区| 兴隆县| 亚洲人妻精品一区二区| 日本夜爽爽一区二区三区| 国产在视频线在精品视频2020| 永久免费无码av在线网站| 亚洲欧美精品综合在线观看| 久久亚洲精品成人综合网| 国产99青青成人A在线| 国产明星精品无码AV换脸| 免费av深夜在线观看| AV无码免费不卡在线观看| 久久国产国内精品国语对白| 综合欧美视频一区二区三区| 亚洲精品国产综合久久一线| 国产国语对白露脸正在播放 | 久久精品国产亚洲av天海翼| 爆乳日韩尤物无码一区| FC2免费人成在线视频|