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

資訊專欄INFORMATION COLUMN

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

freecode / 1924人閱讀

摘要:今天碰到一個需要用做無窮循環的一個案例,頓時腦洞大開。事情是這樣的,有這樣的一群異步函數,將它們封裝成,依次放入一個數組內需要讓數組里的每一個依次進行,最后一個執行完就結束。

今天碰到一個需要用Promise做無窮循環then的一個案例,頓時腦洞大開。
事情是這樣的,有這樣的一群異步函數,

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,依次放入一個數組內:

// 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)];

需要讓數組里的每一個Promise依次進行,最后一個執行完就結束。
我的第一個想法是這樣的:

// 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]();

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

僵了一會,還是谷哥幫助了我,搜到一個非常簡潔的方法:

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

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

// 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]);
};

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

// 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");
});

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

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

12/24更新

感謝wowhy的提示,將我的solution 1的代碼加入一層閉包,已經解決了因內外函數變量產生的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();

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78354.html

相關文章

  • 【譯】前端知識儲備——Promise/A+規范

    摘要:在將來的其他規范中可能會涉及這些沒有提及的內容。它禁止被觸發多次。如果到了狀態,那么所有的回調函數都必須按照他們原有的順序進行調用執行。 概述 自從準備晉級之后,就拖更了很久了,既然晉級弄完了,那么也恢復更新了。 在面試別人的過程中,發現基本上沒有人對整個Promise完全了解,因此希望通過這篇文章來幫助大家了解下Promise的全貌。本文的主要內容是Promise/A+規范的譯文,主...

    Gemini 評論0 收藏0
  • Generator:JS執行權真實操作者

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

    YanceyOfficial 評論0 收藏0
  • 我了解到JavaScript異步編程

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

    RichardXG 評論0 收藏0
  • 前端JS代碼規范

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

    zhiwei 評論0 收藏0
  • Javascript關于異步編程發展

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

    princekin 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<