国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Promise與遍歷(循環(huán),無窮多的then)遇到的問題及三個(gè)解決方案

freecode / 1932人閱讀

摘要:今天碰到一個(gè)需要用做無窮循環(huán)的一個(gè)案例,頓時(shí)腦洞大開。事情是這樣的,有這樣的一群異步函數(shù),將它們封裝成,依次放入一個(gè)數(shù)組內(nèi)需要讓數(shù)組里的每一個(gè)依次進(jìn)行,最后一個(gè)執(zhí)行完就結(jié)束。

今天碰到一個(gè)需要用Promise做無窮循環(huán)then的一個(gè)案例,頓時(shí)腦洞大開。
事情是這樣的,有這樣的一群異步函數(shù),

var func1 = function(callback){
    setTimeout(function(){
      console.log("foo");
      typeof(callback) !== "function" || callback();
    }, 499);
};

var func2 = function(callback){
    setTimeout(function(){
      console.log("bar");
      typeof(callback) !== "function" || callback();
    }, 500);
};

var func3 = function(callback){
    setTimeout(function(){
      console.log("foobar");
      typeof(callback) !== "function" || callback();
    }, 501);
};
// ... more ...

將它們封裝成Promise,依次放入一個(gè)數(shù)組內(nèi):

// promisify those callback functions
var promisify = function(func){
  return function(){
    return new Promise(function(resolve){
      func(resolve);
    });
  }
}

// array can be infinitely long
var func_arr = [promisify(func1), promisify(func2), promisify(func3)];

需要讓數(shù)組里的每一個(gè)Promise依次進(jìn)行,最后一個(gè)執(zhí)行完就結(jié)束。
我的第一個(gè)想法是這樣的:

// solution 1 failed
var master = [];

for (var i = 0; i < func_arr.length; i++) {
  master[i] = function(){
    if (i == 0) {
      return func_arr[i]();
    }
    else {
      return master[i-1]().then(function(){
        return func_arr[i]();
      })
    }
  };
};

master[master.length-1]();

乍看沒有問題啊,每一個(gè)新的master子函數(shù)的值是它上一個(gè)子函數(shù)的值加上一個(gè)then,但是一直報(bào)錯(cuò)——Maximum call stack size exceeded (node) / too much recursion (firefox)。
(12/24圣誕夜更新:已解決,修改了部分代碼見下文)

僵了一會(huì),還是谷哥幫助了我,搜到一個(gè)非常簡潔的方法:

// solution 2 // success
func_arr.reduce(function(cur, next) {
    return cur.then(next);
}, Promise.resolve()).then(function() {
    console.log("job finished");
});

看得我腿都拍出坑了,其實(shí)是我想復(fù)雜了,沒有必要在循環(huán)里不斷地返回閉包函數(shù)等到最后調(diào)用,可以直接在循環(huán)里調(diào)用。
于是心有不甘,reduce()能實(shí)現(xiàn)的我大for豈有實(shí)現(xiàn)不了的道理,實(shí)則也不難,正確方法如下:

// solution 3 // success
var master = [];
master[0] = func_arr[0]();
for (var i = 1; i < func_arr.length; i++) {
  master[i] = master[i-1].then(func_arr[i]);
};

以下再提供一種重復(fù)調(diào)用函數(shù)式(就是遞歸)的方法:

// solution 4 // success
function loop(i) {
  if (i != func_arr.length) {
    return func_arr[i]()
    .then(function() {
      return loop(i+1);
    });
  }
  return Promise.resolve(i);
}

loop(0).then(function(loop_times){
  console.log("job finished");
});

不知道大家還有沒有更好的解決方案,或者能告知我第一個(gè)方案出錯(cuò)的原因吧

================

12/24更新

感謝wowhy的提示,將我的solution 1的代碼加入一層閉包,已經(jīng)解決了因內(nèi)外函數(shù)變量產(chǎn)生的BUG:

// solution 1 // success now
var master = [];

for (var i = 0; i < func_arr.length; i++) {
  master[i] = (function(j){
    return function(){
      if (j == 0) {
        return func_arr[j]();
      }
      else {
        return master[j-1]().then(function(){
          return func_arr[j]();
        })
      }
    }
  })(i);
};

var execute = master[master.length-1];
execute();

乍看這一串代碼很長,對(duì)比之前的方案顯得完全多余,在我看來,可以生成在外部其他的上下文內(nèi)進(jìn)行獨(dú)立調(diào)用的函數(shù)要更符合我大腦的思維方式:)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/78354.html

相關(guān)文章

  • 【譯】前端知識(shí)儲(chǔ)備——Promise/A+規(guī)范

    摘要:在將來的其他規(guī)范中可能會(huì)涉及這些沒有提及的內(nèi)容。它禁止被觸發(fā)多次。如果到了狀態(tài),那么所有的回調(diào)函數(shù)都必須按照他們?cè)械捻樞蜻M(jìn)行調(diào)用執(zhí)行。 概述 自從準(zhǔn)備晉級(jí)之后,就拖更了很久了,既然晉級(jí)弄完了,那么也恢復(fù)更新了。 在面試別人的過程中,發(fā)現(xiàn)基本上沒有人對(duì)整個(gè)Promise完全了解,因此希望通過這篇文章來幫助大家了解下Promise的全貌。本文的主要內(nèi)容是Promise/A+規(guī)范的譯文,主...

    Gemini 評(píng)論0 收藏0
  • Generator:JS執(zhí)行權(quán)真實(shí)操作者

    摘要:執(zhí)行權(quán)由此單向穩(wěn)定的在不同函數(shù)中切換。調(diào)用函數(shù)后,引擎會(huì)為其開辟一個(gè)獨(dú)立的函數(shù)執(zhí)行棧以下簡稱棧。執(zhí)行權(quán)再次回到外部。成功執(zhí)行完函數(shù),則改變的狀態(tài)為成功。執(zhí)行函數(shù)返回的遍歷器對(duì)象會(huì)繼承函數(shù)的原型對(duì)象。遇到下一個(gè)斷點(diǎn),交出執(zhí)行權(quán)傳出返回值。 前言 ES6提供了一種新型的異步編程解決方案:Generator函數(shù)(以下簡稱G函數(shù))。它不是使用JS現(xiàn)有能力按照一定標(biāo)準(zhǔn)制定出來的東西(Promis...

    YanceyOfficial 評(píng)論0 收藏0
  • 我了解到JavaScript異步編程

    摘要:接下來我們看下三類異步編程的實(shí)現(xiàn)。事件監(jiān)聽事件發(fā)布訂閱事件監(jiān)聽是一種非常常見的異步編程模式,它是一種典型的邏輯分離方式,對(duì)代碼解耦很有用處。 一、 一道面試題 前段時(shí)間面試,考察比較多的是js異步編程方面的相關(guān)知識(shí)點(diǎn),如今,正好輪到自己分享技術(shù),所以想把js異步編程學(xué)習(xí)下,做個(gè)總結(jié)。下面這個(gè)demo 概括了大多數(shù)面試過程中遇到的問題: for(var i = 0; i < 3; i++...

    RichardXG 評(píng)論0 收藏0
  • 前端JS代碼規(guī)范

    摘要:縮進(jìn)為個(gè)空格句末必須用分號(hào)結(jié)尾待定就無分號(hào)注釋單行注釋多行注釋代碼注釋和再提交重要函數(shù)或者類等都要添加頭描述字符串拼接應(yīng)使用數(shù)組保存字符串片段,使用時(shí)調(diào)用方法。 前言 下面這幾點(diǎn)將工作中所踩的一些坑簡單整理了一下,團(tuán)隊(duì)幾個(gè)人開發(fā),一些默契就比較重要,可以提高開發(fā)效率和代碼的可讀性 命名,編碼和注釋 命名 A.文件夾命名:文件夾、文件的命名與命名空間應(yīng)能代表代碼功能,可讀性強(qiáng),如hubB...

    zhiwei 評(píng)論0 收藏0
  • Javascript關(guān)于異步編程發(fā)展

    摘要:前言轉(zhuǎn)簡體重新排版布局代碼全面使用并且直接附上輸出結(jié)果補(bǔ)充細(xì)節(jié)補(bǔ)充內(nèi)容增加例子說明新增和在遍歷情況下怎么使用上文講了關(guān)于執(zhí)行機(jī)制單線程同異步任務(wù)事件循環(huán)的知識(shí)點(diǎn)我們知道在某一時(shí)刻內(nèi)只能執(zhí)行特定的一個(gè)任務(wù)并且會(huì)阻塞其它任務(wù)執(zhí)行為了解決這個(gè) 前言 PS:2018/08/08 轉(zhuǎn)簡體2018/08/09 重新排版布局,代碼全面使用ES6并且直接附上輸出結(jié)果,補(bǔ)充細(xì)節(jié)2018/08/13 補(bǔ)充...

    princekin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<