【问题标题】:Not reaching aync callback, response hangs未达到异步回调,响应挂起
【发布时间】:2015-11-23 14:20:30
【问题描述】:

我遇到了一个问题,我不确定要采取什么步骤来解决它。现在所有数据都被正确检索但是 responseCallback 永远不会触发,因此我没有到达 res.json 与响应数组的调用。这里的任何指导将不胜感激!谢谢。

为了澄清问题在于 aysnc.each 回调。

  var updatedBusinesses = [];
  googleplaces.radarSearch({location:"lat,long",radius:"10000",keyword:"keywordhere"},function(err,response){
   if(err){return next(err);}

   async.each(response.results,function(currResponse,responseCallback){
    Business.findOne({"placesId":currResponse.place_id,"claimed":true}).populate({path:'services',select:''}).exec(function(err,business){
     if(err){return next(err);}

     if(business !== null){
       Service.populate(business.services,{path:'employees',select:'_id appointments firstName lastName username avatarVersion'},function(err,newBusiness){
        if(err){return next(err);}

        googleplaces.placeDetailsRequest({placeid:business.placesId},function(error,placesResult){
         if(error){return responseCallback(error);}

         console.log("RESULT OF THE GOOGLE PLACES DETAIL SEARCH")
         placesResult.result.info = business;
         updatedBusinesses.push(placesResult.result);
         // Here the data is populated and correct.
         // console.log(updatedBusinesses)
         responseCallback();

       });
     })
   }
 })
},function(err){
   if(err){return next(err);}
   console.log("called")
   res.json(updatedBusinesses);
 })
})

这是我希望将更新的业务信息返回给客户的地方,但是这永远不会触发。

},function(err){
   if(err){return next(err);}
   console.log("called")
   res.json(updatedBusinesses);
 })
})

【问题讨论】:

  • 这里有多个回调。你能确定哪些没有被解雇吗?
  • 是的,抱歉,async.each responseCallback
  • 你是否到达了这个``` // console.log(updatedBusinesses)``,如果你取消注释它会给你正确的结果吗?
  • 是的,代码到达了该语句并且确实到达了。这正是我想返回给客户端的数据。
  • 那么你的回调应该是 responseCallback(null, updatedBusinesses);

标签: node.js asynchronous express mongoose mongoose-populate


【解决方案1】:

将您的代码 responseCallback(); 更改为 responseCallback(null, [your-result]); 我认为应该可以完成这项工作

var updatedBusinesses = []; googleplaces.radarSearch({location:"lat,long",radius:"10000",keyword:"keywordhere"},function(err,response){

if(err){return next(err);}

async.each(response.results,function(currResponse,responseCallback){    Business.findOne({"placesId":currResponse.place_id,"claimed":true}).populate({path:'services',select:''}).exec(function(err,business){
 if(err){return next(err);}

 if(business !== null){
   Service.populate(business.services,{path:'employees',select:'_id appointments firstName lastName username avatarVersion'},function(err,newBusiness){
    if(err){return next(err);}

    googleplaces.placeDetailsRequest({placeid:business.placesId},function(error,placesResult){
     if(error){return responseCallback(error);}

     console.log("RESULT OF THE GOOGLE PLACES DETAIL SEARCH")
     placesResult.result.info = business;
     updatedBusinesses.push(placesResult.result);
     // Here the data is populated and correct.
     // console.log(updatedBusinesses)
     responseCallback(null, updatedBusinesses);

   });
 })
} }) },function(err, updatedBusinesses){
   if(err){return next(err);}
   console.log("called")
   res.json(updatedBusinesses);
 })
})

【讨论】:

  • 感谢 bianca,但是我已经尝试过这个解决方案,但它不起作用。基于位于此处的异步库文档:github.com/caolan/async#each 我认为我不能将第二个参数传递给该回调。当我尝试这种方法时,没有数据被传递..这意味着 updatedBusinesses 数组没有被传递到回调中。响应仍然挂起。
【解决方案2】:

async.each() 期望每次迭代都会调用一个回调 (responseCallback)。如果它没有被调用,它就会坐在那里等待它。这就是为什么您的更新业务部分永远不会被调用的原因。

在您的 async.each() 内部,有许多地方调用 next(),这不是 async.each() 的迭代回调 (responseCallback)。这是正确调用回调的修改后的代码:

var updatedBusinesses = [];

googleplaces.radarSearch({location:"lat,long",radius:"10000",keyword:"keywordhere"},function(err,response){
    if(err){return next(err);}

    async.each(response.results,function(currResponse,responseCallback){
        Business.findOne({"placesId":currResponse.place_id,"claimed":true}).populate({path:'services',select:''}).exec(function(err,business){
            if(err){
              return responseCallback(err);// <== calling responseCallback instead of next() 
            } 

            // in case of business === null/undefined, I'm not seeing any 
            // callback getting called, it needs to be called inside 
            // async.each() no matter which condition it is
            if (!business) {
               // call responseCallback to continue on with async.each()
                return responseCallback();
            }
            Service.populate(business.services,{path:'employees',select:'_id appointments firstName lastName username avatarVersion'},function(err,newBusiness){
                if(err){
                  return responseCallback(err);// <== calling responseCallback instead of next() 
                }

                googleplaces.placeDetailsRequest({placeid:business.placesId},function(error,placesResult){
                    if(error){return responseCallback(error);}

                    console.log("RESULT OF THE GOOGLE PLACES DETAIL SEARCH")
                    placesResult.result.info = business;
                    updatedBusinesses.push(placesResult.result);
                    // Here the data is populated and correct.
                    // console.log(updatedBusinesses)
                    responseCallback();
                });
            })
        })
    },function(err){
        if(err){return next(err);}
        console.log("called");
        res.json(updatedBusinesses);
    });
}); 

所以现在对于 async.each() 中的每个条件都会调用 responseCallback()。它现在应该归结为代码的“更新的业务信息”部分。

【讨论】:

  • 谢谢!这很有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 1970-01-01
相关资源
最近更新 更多