使用nodejs的承诺,我如何链接结果

时间:2017-07-27 02:02:11

标签: node.js mongodb mongoose promise

我正在使用mongob mongodb。

我有一些收藏品与下一个模型:

一个。型号:产品

湾型号:详情

我需要返回一个包含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);

    });

1 个答案:

答案 0 :(得分:2)

对于此代码段,您应该使用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; 
 }