嵌套Promise.map()不返回任何结果

嵌套Promise.map()不返回任何结果

问题描述:

我想使用承诺来执行循环内循环。我希望内部循环应该完成它的迭代,然后外部循环应该迭代。嵌套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

尽我的代码的理解,你想这么简单的东西:

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)了解更多关于_.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