如何在异步调用期间填充数组并将其发送到响应对象中

时间:2015-05-22 19:48:42

标签: javascript arrays node.js mongoose mongoose-populate

这是我想要做的一个例子,检索mongo db中的所有帖子,为每个帖子填充作者然后使用author对象从Cloudinary检索个人资料图片。

这样做的正确方法是什么?我已经尝试了很多方法来填充数组并在响应中发送它们但是由于异步调用它们在发送res之前从不运行。

router.get('/posts',auth, function(req, res, next) {
  //var id = req.payload._id;
  Post.find(function(err, posts){
    if(err){ return next(err); }
    posts.forEach(function(post){
      post.populate('author',function(err,post){
        post.image = cloudinary.image("v"+post.author.avatarVersion+"/profile/"+post.author._id,{
          width:100, height:100,crop:'thumb',gravity:'face',radius:'max'
        })
        //here the post object is updated
        console.log(post)
      })
    })
    //res.json(some posts array);
  });
});

感谢Dan Moldovan!

router.get('/posts',auth, function(req, res, next) {
  var id = req.payload._id;

  Post.find({}).populate('author').exec(function(err,posts){
    if(err){ return next(err); }
    var updatedPosts = [];
    posts.forEach(function(post){
      post.image = cloudinary.image("v"+post.author.avatarVersion+"/profile/"+post.author._id,{
          width:100, height:100,crop:'thumb',gravity:'face',radius:'max'
      })
      updatedPosts.push(post);
    })
    res.json(updatedPosts);
  })

2 个答案:

答案 0 :(得分:1)

您可以将<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <v4:RateReply xmlns:rate="http://fedex.com/ws/rate/v5" xmlns:v4="http://fedex.com/ws/rate/v4"> <ns1:TransactionDetail xmlns:ns1="http://fedex.com/ws/rate/v4" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <ns1:CustomerTransactionId> *** Rate Request v4 using PHP ***</ns1:CustomerTransactionId> </ns1:TransactionDetail> <ns1:Version xmlns:ns1="http://fedex.com/ws/rate/v4" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <ns1:ServiceId>crs</ns1:ServiceId> <ns1:Major>4</ns1:Major> <ns1:Intermediate>0</ns1:Intermediate> <ns1:Minor>0</ns1:Minor> </ns1:Version> <v4:RateReplyDetails> <v4:ServiceType>PRIORITY_OVERNIGHT</v4:ServiceType> <v4:PackagingType>YOUR_PACKAGING</v4:PackagingType> <v4:IneligibleForMoneyBackGuarantee>false</v4:IneligibleForMoneyBackGuarantee> <v4:OriginServiceArea>A1</v4:OriginServiceArea> <v4:DestinationServiceArea>A1</v4:DestinationServiceArea> <v4:SignatureOption>SERVICE_DEFAULT</v4:SignatureOption> <v4:ActualRateType>PAYOR_ACCOUNT</v4:ActualRateType> <v4:RatedShipmentDetails> <v4:EffectiveNetDiscount> <v4:Currency>USD</v4:Currency> <v4:Amount>28.02</v4:Amount> </v4:EffectiveNetDiscount> <v4:ShipmentRateDetail> <v4:RateType>PAYOR_ACCOUNT</v4:RateType> <v4:RateScale>1</v4:RateScale> <v4:PricingCode>PACKAGE</v4:PricingCode> <v4:DimDivisor>194</v4:DimDivisor> <v4:FuelSurchargePercent>16.5</v4:FuelSurchargePercent> <v4:TotalBillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalBillingWeight> <v4:TotalDimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalDimWeight> <v4:TotalBaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:TotalBaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:TotalNetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:TotalNetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:TotalSurcharges> <v4:TotalNetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:TotalNetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:TotalNetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:TotalNetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:ShipmentRateDetail> <v4:RatedPackages> <v4:EffectiveNetDiscount> <v4:Currency>USD</v4:Currency> <v4:Amount>28.02</v4:Amount> </v4:EffectiveNetDiscount> <v4:PackageRateDetail> <v4:RateType>PAYOR_ACCOUNT</v4:RateType> <v4:RatedWeightMethod>DIM</v4:RatedWeightMethod> <v4:BillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:BillingWeight> <v4:DimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:DimWeight> <v4:BaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:BaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:NetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:NetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:TotalSurcharges> <v4:NetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:NetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:NetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:NetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:PackageRateDetail> </v4:RatedPackages> </v4:RatedShipmentDetails> <v4:RatedShipmentDetails> <v4:EffectiveNetDiscount> <v4:Currency>USD</v4:Currency> <v4:Amount>28.02</v4:Amount> </v4:EffectiveNetDiscount> <v4:ShipmentRateDetail> <v4:RateType>RATED_ACCOUNT</v4:RateType> <v4:RateScale>1</v4:RateScale> <v4:PricingCode>PACKAGE</v4:PricingCode> <v4:DimDivisor>194</v4:DimDivisor> <v4:FuelSurchargePercent>16.5</v4:FuelSurchargePercent> <v4:TotalBillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalBillingWeight> <v4:TotalDimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalDimWeight> <v4:TotalBaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:TotalBaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:TotalNetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:TotalNetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:TotalSurcharges> <v4:TotalNetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:TotalNetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:TotalNetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:TotalNetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:ShipmentRateDetail> <v4:RatedPackages> <v4:EffectiveNetDiscount> <v4:Currency>USD</v4:Currency> <v4:Amount>28.02</v4:Amount> </v4:EffectiveNetDiscount> <v4:PackageRateDetail> <v4:RateType>RATED_ACCOUNT</v4:RateType> <v4:RatedWeightMethod>DIM</v4:RatedWeightMethod> <v4:BillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:BillingWeight> <v4:DimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:DimWeight> <v4:BaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:BaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:NetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>52.25</v4:Amount> </v4:NetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:TotalSurcharges> <v4:NetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:NetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:NetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>60.87</v4:Amount> </v4:NetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>8.62</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:PackageRateDetail> </v4:RatedPackages> </v4:RatedShipmentDetails> <v4:RatedShipmentDetails> <v4:ShipmentRateDetail> <v4:RateType>PAYOR_LIST</v4:RateType> <v4:RateScale>1552</v4:RateScale> <v4:RateZone>5</v4:RateZone> <v4:PricingCode>PACKAGE</v4:PricingCode> <v4:DimDivisor>194</v4:DimDivisor> <v4:FuelSurchargePercent>16.5</v4:FuelSurchargePercent> <v4:TotalBillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalBillingWeight> <v4:TotalDimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalDimWeight> <v4:TotalBaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:TotalBaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:TotalNetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:TotalNetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>12.59</v4:Amount> </v4:TotalSurcharges> <v4:TotalNetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:TotalNetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:TotalNetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:TotalNetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>12.59</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:ShipmentRateDetail> <v4:RatedPackages> <v4:PackageRateDetail> <v4:RateType>PAYOR_LIST</v4:RateType> <v4:RatedWeightMethod>DIM</v4:RatedWeightMethod> <v4:BillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:BillingWeight> <v4:DimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:DimWeight> <v4:BaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:BaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:NetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:NetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>12.59</v4:Amount> </v4:TotalSurcharges> <v4:NetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:NetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:NetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:NetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> <v4:SurchargeType>INSURED_VALUE</v4:SurchargeType> <v4:Description>Insured value</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:Amount> </v4:Surcharges> <v4:Surcharges> <v4:SurchargeType>FUEL</v4:SurchargeType> <v4:Description>Fuel</v4:Description> <v4:Amount> <v4:Currency>USD</v4:Currency> <v4:Amount>12.59</v4:Amount> </v4:Amount> </v4:Surcharges> </v4:PackageRateDetail> </v4:RatedPackages> </v4:RatedShipmentDetails> <v4:RatedShipmentDetails> <v4:ShipmentRateDetail> <v4:RateType>RATED_LIST</v4:RateType> <v4:RateScale>1552</v4:RateScale> <v4:RateZone>5</v4:RateZone> <v4:PricingCode>PACKAGE</v4:PricingCode> <v4:DimDivisor>194</v4:DimDivisor> <v4:FuelSurchargePercent>16.5</v4:FuelSurchargePercent> <v4:TotalBillingWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalBillingWeight> <v4:TotalDimWeight> <v4:Units>LB</v4:Units> <v4:Value>13.0</v4:Value> </v4:TotalDimWeight> <v4:TotalBaseCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:TotalBaseCharge> <v4:TotalFreightDiscounts> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalFreightDiscounts> <v4:TotalNetFreight> <v4:Currency>USD</v4:Currency> <v4:Amount>76.3</v4:Amount> </v4:TotalNetFreight> <v4:TotalSurcharges> <v4:Currency>USD</v4:Currency> <v4:Amount>12.59</v4:Amount> </v4:TotalSurcharges> <v4:TotalNetFedExCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:TotalNetFedExCharge> <v4:TotalTaxes> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalTaxes> <v4:TotalNetCharge> <v4:Currency>USD</v4:Currency> <v4:Amount>88.89</v4:Amount> </v4:TotalNetCharge> <v4:TotalRebates> <v4:Currency>USD</v4:Currency> <v4:Amount>0.0</v4:Amount> </v4:TotalRebates> <v4:Surcharges> 查询链接到第一个查询,然后进行最终回调,例如

populate

答案 1 :(得分:1)

Dan的解决方案是正确的,但我想解释你遇到的问题。因为post.populate()是数据库调用,所以它意味着代码是异步的。这意味着forEach()中的下一篇文章将在.populate()完成上一篇文章之前开始投放。这意味着并非所有帖子都会在res.json()执行之前完成。解决方案(在这种情况下不需要,但可以由您当前的代码使用)是使用async library

var async = require("async");

router.get('/posts',auth, function(req, res, next) {
    var id = req.payload._id;

    Post.find(function (err, posts) {
        if (err) {
            return next(err);
        }

        // This is a forEach that waits until all posts are populated before moving on
        async.each(posts, function (currentPost, postCallback) {

            currentPost.populate("author", function (err, post) {

                if (err) {
                    return postCallback(err);
                }
                post.image = cloudinary.image("v" + post.author.avatarVersion + "/profile/" + post.author._id, {
                    width: 100, height: 100, crop: 'thumb', gravity: 'face', radius: 'max'
                });
                // the callback function for the current post
                postCallback(); 
            });
        }, function (error) {
            // the final callback function once all postCallback()'s have been executed, or an error

            if (error) {
                return next(error);
            }
            // here, everything is finished
            res.json(posts);
        });
    });
});

同样,Dan的解决方案是正确的,所以不要使用此代码。当遇到这样的问题时,请记住这一点。