【问题标题】:Promise with nodejs, how could I chain results用nodejs承诺,我怎么能链接结果
【发布时间】:2018-01-02 13:16:29
【问题描述】:

我正在将 mongodb 与 mongoose 一起使用。

我有一些与下一个模型的集合:

一个。型号:产品

b.型号:详情

我需要返回一个包含 Product 中总项目的数据集,并且对于每个产品项目,我需要通过在 Model Details 中循环您的详细信息来计算数量。

我的问题是如何在我的数据数组中设置数量,在执行“promise_3”之后。 我需要知道数据数组的索引才能做到这一点,但我该怎么做呢?

结果会是这样的:

response:{
total:1012, 
data:[
{id:'1',name:'xx', quantity:10},
{id:'2',name:'yy', quantity:110},
{id:'3',name:'zz', quantity:130},
...
]}

//我的承诺代码

var response={};
var promise_1=Product.count({}).lean().exec();

var prommise_2=function (data){
       return Product.find(conditions)
        .limit(pageSize)
        .skip(pageSize*(pageNumber-1))
        .sort(oorder)
        .lean()
        .exec();
   }


var prommise_3= function (item){
        return Details.aggregate(
                    [
                            { "$match": { 
                                cod_material: item._id
                            }},
                            {$lookup:
                              {
                                from: "estoqueMov", //use the name of database collection not mongoose model
                                localField: "cod_mov",
                                foreignField: "_id",
                                as: "mov_doc"
                              }
                            },

                            { $unwind: "$mov_doc" },
                            {$lookup:
                              {
                                from: "Details", //use the name of database collection not mongoose model
                                localField: "mov_doc.cod_tipo_mov",
                                foreignField: "_id",
                                as: "tipo_mov_doc"
                              }
                            },

                            { $unwind: "$tipo_mov_doc"},
                            { "$group": {
                                _id: "$cod_material",
                                total: { "$sum": 
                                        {"$multiply": 
                                         ["$quantidade",{"$cond":[
                                         {"$eq":["$tipo_mov_doc.tipo","Entrada"]} , 1,-1]}] 
                                        }
                                        } 
                            }}

                    ]);
    }

    //promise_1 is done
    promise_1.then( function(count){
         response.total=count;
         return promise_2() 
    })
    .then( function (data){
        response.data=data;
        for (var i = 0; i < response.data.length; i++) { 
          var item=response.data[i];
          //??item.quantity=0;
          return promise_3(item) 
        }
    })
    .then( function (results){
        var total=results.length>0?results[0].total:0;
        //Here is my problem How could I set the response.data index array??
        response.data[??????].quantity=total;
        callback(null,response,res);

    });

【问题讨论】:

  • 在第二个回调中,你在 for 循环的中间return。我不认为那是你想要的。
  • @Bergi,我需要使用 promise_3 计算每个产品项目的数量。我的意图是创建一个循环并调用 promise_3。你能提出一些不同的建议吗?
  • 好吧,要么生成一个promise_3 承诺数组,使用Promise.all,然后以几乎相同的方式迭代results(保留顺序,因此您可以轻松地使用索引到数据数组中)。或者你将那些.then() 调用放在循环中,这样每个promise_3 都有自己的回调(然后可以通过闭包provided that the loop scope is correct 使用索引)。无论如何,放下或移动那个return

标签: node.js mongodb mongoose promise


【解决方案1】:

对于这个sn-p,你应该使用Promise.all 因为您要做的实际上是为数组中的每个项目解析 1 个承诺。

.then( function (data){
        response.data=data;
        for (var i = 0; i < response.data.length; i++) { 
          var item=response.data[i];
          //??item.quantity=0;
          return promise_3(item) 
        }
    })

它看起来像这样

 .then( function (data){
            var promises = [];
            response.data=data;
            for (var i = 0; i < response.data.length; i++) { 
              var item=response.data[i];
              //??item.quantity=0;
              promises.push(promise_3(item)); 
            }
            return Promise.all(promises);
        })

现在基本上你的下一个.then 将不会运行,直到promises 数组中的所有承诺都得到解决。

注意:生成的 promise.all 数组的顺序在完全解析后会保持其元素顺序。

鉴于最后一个 .then 现在将获取一个数据数组,您需要将其功能包装在一个循环中——类似这样(不是 100% 确定这是否是您想要的,但是您应该明白了。):

 for (var i = 0; i < results.length; i++) { 
          var total=results[i].length>0?results[i].total:0;
          response.data[i].quantity=total; 
 } 

【讨论】:

  • 谢谢。它解决了部分问题。对最后一个“then”的任何建议:response.data[??????].quantity=total;
  • @LuizAlves “再次链接它”。这里的答案是return Promise.all(),所以它返回为Promise,这意味着您只需使用.then() 继续链。这才是重点。它实际上甚至说“现在基本上你的下一个.then() 将不会运行,直到promise 数组中的所有promise 都已解决。”
  • @Neil Lunn 好的,我在最后一步已经有了一个链。我的问题是我需要设置 response.data[index].quantity=total 而我没有从 Promisse.All 的返回中获得这个“索引”
  • @88jayto 嗨,“response.data”的“results”索引是否相同?我认为它可能会有所不同,因为 promise.all 并行运行所有承诺,并且结果中的顺序没有保证。我说的对吗?
  • @LuizAlves 保证了数组内元素的顺序。 stackoverflow.com/questions/28066429/… 你可能会想到 promise 的解决顺序,这并不能保证,但这是不相关的,不应该引起任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 2015-01-06
  • 2021-02-18
  • 2018-11-03
  • 2016-08-28
  • 1970-01-01
相关资源
最近更新 更多