2015-09-01 40 views
0

我有一個包含用戶信息的對象數組。(節點)運行n次的動態承諾

var names=[{name: 'yoda', 
      address:'123 Compton', 
      email:'[email protected]'}, 
      {name: 'darth vader', 
      address:'69 harlem', 
      email:'[email protected]'},{....}] 

這是一個列表,範圍可以從100到1000個用戶。 問題是我需要從網絡和數據庫請求/提取關於每個用戶的信息,並創建一個包含每個用戶更多詳細信息的新數組。這將是3個來源。現在每次拉動需要10毫秒到1分鐘。 這是我跳轉到承諾。 (「本地承諾」),例如:

require("native-promise-only"); 

function getFile(file) { 
    return new Promise(function(resolve){ 
     fakeAjax(file,resolve); 
    }); 
} 
//Recursive call 
function recursivePromise(originalArray, newArray){ 
if(isEmpty(originalArray)){ 
    store(newArray); 
    display(newArray); 
} 
else{ 
    var currentItem = originalArray[0]; 
    var p1 = getFile(currentItem.name); 
    var p2 = getFile(currentItem.address); 
    var p3 = getFile(currentItem.email); 

    var newDataItem={}; 
    p1.then(function(msg){ 
    //TODO check status 
    newDataItem.nameinfo= msg; 
    return p2; 
    }) 

    .then(function(msg){ 
    //TODO check status 
    newDataItem.addressinfo= msg 
    return p3; 
    }) 

    .then(function(msg){ 
    newDataItem.emailinfo= msg 
    newArray.add(newDataItem); 
    recursivePromise(originalArray.shift(), newArray) 
    }); 
} 
} 
var new_array=[]; 
recursivePromise(names, new_array); 

這是一個粗略的代碼,我有類似的東西,它的工作原理!有些。但是我的一個錯誤告訴我,我可能會設置一個未來的失敗。我正在遞歸地做這件事,因爲這個項目在'名字'中的位置很重要。所以他們需要按順序處理。

+0

什麼是'水果'?你爲什麼要「轉移」它?數組上的'.add()'是什麼? – Bergi

+0

您是否想要串行運行請求(在第一個完成之前不要啓動第二個請求)還是希望並行運行它們(最多一次請求X個請求)? – jfriend00

回答

0

問題,因爲我看到他們:

編碼錯誤:

  • fruits出來的無處;據推測originalArray.shift()是有意的。
  • array.shift()從數組中刪除第0個元素並返回被刪除的元素,而不是數組。
  • originalArray將被銷燬,這不是一個好主意。
  • .add()不是數組方法,推測是.push()是有意的。

模式問題:

  • p1.then(...).then(...)鏈是建立一個newDataItem相當麻煩的辦法; Promise.all(p1, p2, p3).then(...)將更具可讀性,newDataItem內置在單個表達式中。
  • 遞歸是沒有必要的;該過程將更簡單地編碼爲...; Promise.all(arrayOfPromises).then(function(newArray) {...});(這是Promise.all()的第二次使用);雖然承諾將以他們喜歡的任何順序進行結算,但是newArray將與originalArray一致。
  • newArray可以在內部生成,無需通過[]
function process(originalArray) { 
    var promises = originalArray.map(function(currentItem) { 
     var p1 = getFile(currentItem.name); 
     var p2 = getFile(currentItem.address); 
     var p3 = getFile(currentItem.email); 
     return Promise.all([p1, p2, p3]).then(function(results) { 
      return { 
       nameinfo: results[0], 
       addressinfo: results[1], 
       emailinfo: results[2] 
      }; 
     }); 
    }); 
    return Promise.all(promises).then(function(newArray) { 
     display(newArray); 
     return newArray; 
    }); 
} 
process(names).then(function(newArray) { 
    store(newArray); 
}); 

display(newArray)store(newArray)既可以在內部或外部執行。我將它們分成兩部分以展示兩種可能性。

+0

(゚o゚) - 看起來很乾淨。謝謝。我不得不快速提出一個解決方案,並且遞歸是我所能想到的。你把我的黑客羞愧。 – user3699878

+0

「The Collection Kerfuffle」部分** [這裏](http://taoofcode.net/promise-anti-patterns/)**應該爲你做有趣的閱讀。 –