2016-11-22 140 views
0

我想使用承諾來執行循環內循環。我希望內部循環應該完成它的迭代,然後外部循環應該迭代。嵌套Promise.map()不返回任何結果

例如: -

arr1 = [1,2,3,4]; 
arr2 = [5,6,7,8]; 

loopOfArr1{ 
    loopOfArr2{ 
     //functionality 
    } 
} 

我要爲ARR1的每個值,ARR2的循環應該得到執行。而且這兩個循環將如何完成同步。

下面是一個使用我的代碼的承諾: -

exports.getAtpagesWeights = function(atpagesDataArray,selectedTagsIds, taggings, callback){ 
    var atpageData, forHubCount; 
    return Promise.map(selectedTagsIds, function(tag, index, count){ 
     return Promise.map(taggings, function(tagging, index, count){ 
      return new Promise(function(resolve, reject){ 
       var atpageArray = _.filter(atpagesDataArray, function(item){ 
        if(tagging.taggable_id == item.id && tagging.tag_id == tag){ 
         item = item.toObject(); 
         item.rank_weight = tagging.atpages_weight; 
         resolve(item); 
        } 
       }) 
      }) 
     })  
    }).then(function(result){ 
     console.log(result); 
     callback(null, result); 
    }).catch(function(error){ 
     callback(error, null); 
    }) 
} 

但是,當我檢查日誌,正在打印什麼,誰能告訴我要去哪裏錯了,或者是還有什麼更好的辦法?

+1

我在代碼中看不到任何異步。那麼你用什麼承諾呢?另外,承諾和回調不會很好地混合。避免混合它們。 – Tomalak

+0

所以如果我使用forEach而不是承諾,我將如何能夠得到我的結果數組,請問您能用一個簡單的例子來支持這個嗎? –

+0

不知道輸入是什麼,你試圖建立什麼輸出。但這裏沒有異步。忘記回調。忘記承諾。拋出所有的東西。編寫一個簡單的函數,在其參數上運行循環,計算一個值並返回該值。 – Tomalak

回答

2

盡我的代碼的理解,你想這麼簡單的東西:

exports.getAtpagesWeights = function (atpagesData, selectedTagIds, taggings) { 
    var atpagesIndex = {}, 
     atpagesWeights = atpagesData.map(item => { 
      var weighted = item.toObject(); 
      weighted.rank_weight = null; 
      atpagesIndex[item.id] = weighted; 
      return weighted; 
     }); 

    taggings.filter(t => selectedTagIds.includes(t.id)).forEach(t => { 
     atpagesIndex[t.taggable_id].rank_weight = t.atpages_weight; 
    }); 

    return atpagesWeights; 
}; 

這將返回從atpagesData項目直接派生的對象的平面陣列,與rank_weight增加了選擇的個體。

作爲一般規則:異步連續回調僅用於一個目的和一個用途:處理異步操作。

承諾是繼續之上的一個抽象層次。從本質上講,它們是火 - 一次更好的處理回調,但它們仍然是回調的核心。

如果您的代碼沒有任何異步路徑(並且您的代碼示例看起來不像它),那麼您不需要callback參數,也不需要任何承諾。把事情簡單化。

+0

嘿,你的回答非常清晰明瞭,但是在使用你提供的代碼時,我獲得了數組中rank_weight鍵的空值。 –

+1

因爲你既沒有提供樣本輸入,也沒有提供所需的輸出,也沒有任何解釋你的代碼應該在概念上做什麼,所以它不能正常工作並不奇怪。所以......就像我分析你的代碼來提出一個(可能的)簡化一樣,現在輪到你分析我的代碼並理解它並將這些原則應用於你的問題。 – Tomalak

+0

「*回調函數僅用於一個目的,僅用於一個用途:處理異步操作*」 - 否。你自己答案中的代碼證明你錯了。將回調放在圖片之外,並說承諾只適用於異步操作,並且您將獲得我的讚賞。 – Bergi

1

1)瞭解更多關於_.filter方法,您的使用是錯誤的

2)上次答應不解決,不拒絕,因此您的控制檯打印什麼

3),而不是這種結構(如果它是不是promisification)

return new Promise(function(resolve, reject){ 
    resolve(somthing) 
}) 

更好地利用這種結構

return Promise.resolve() 
    .then(function(){ 
     return somthing; 
    }) 

4)我給你的代碼添加一些優雅

exports.getAtpagesWeights = function(atpagesDataArray, selectedTagsIds, taggings, callback){ 
    var atpageData, forHubCount; 
    return Promise.map(selectedTagsIds, function(tag, index, count){ 
     return Promise.resolve() 
      .then(function() { 
       return Promise.filter(taggings, function(tagging) { 
        return tagging.tag_id === tag; 
       }) 
      }) 
      .then(function(taggings) { 
       return Promise.filter(atpagesDataArray, function(item) { 
        return _.chain(taggings) 
         .map('taggable_id') 
         .includes(item.id) 
         .value(); 
       }); 
      }) 
      .then(function(atpagesDataArray) { 
       return Promise.map(atpagesDataArray, function(item) { 
        item = item.toObject(); 
        item.rank_weight = _.chain(taggings) 
         .find({taggable_id: item.id}) 
         .get('atpages_weight') 
         .value(); 
        return item; 
       }); 

      }) 
      .value(); 
     })  
    }) 
    .then(function(result){ 
     console.log(result); 
     callback(null, result); 
    }) 
    .catch(function(error){ 
     callback(error, null); 
    }) 
} 
+0

看起來更像是你添加了一堆毫無意義的承諾... – Bergi

+0

@Bergi我讓代碼更具可讀性和確定性。一些承諾是毫無意義的,但我以作者爲例,作爲例子 – stasovlas

+0

好吧,優雅是主觀的(我會發現更簡潔的代碼更好),但我完全同意你的前三點 – Bergi