我发布了一个带有jQuery的json字符串到我的NodeJS后端,并且遇到了后端发布数据的问题。看起来后端在某处阻塞,但我无法找到它。因此,我的POSTS保持状态挂起,有时它返回OK 200。
我的代码循环使用async.forEach retValTravelInsurerList,它是一个由23家保险公司组成的数组。我有一个嵌套的async.forEach,它使用值设置构造函数,并在filterTravelInsurerCoverage中执行查询。这意味着通过Mongoose(MongoDB)数据库执行23个查询。
如果在过滤器TerminalInsurerCoverage数组中找到它们,我只需要retValTravelInsurerList中的项目,我将填充一个新数组(retValTravelInsurerAndCoverageList),其中存储了所有需要的项目。
如果travelinsurercoverage具有retValTravelInsurerList =>中所有项目的覆盖范围,则POST状态没有问题。让我们说23。
但是如果生成的数组(retValTravelInsurerAndCoverageList)长度小于(travelinsurercoverage)长度,则会发生POST问题,如果我向服务器发布了几次,则状态会在Chrome的javascript控制台中保持“PENDING”。
在我看来,NodeJS调用堆栈中仍有一些项目阻塞了未来的POSTS,即使在返回callback()时也是如此;被称为。
有人知道如何解决这个问题吗?
顺便说一句:我使用异步库,并在返回callback()之后;被称为res.send(JSON.stringify(retValTravelInsurerAndCoverageList));被称为。
function(callback) {
var count = 0;
async.forEach(retValTravelInsurerList, function(item, callback1) {
count++;
travelinsurercoverageMdl.constructorTravelInsurerCoverage('', item._id, item.familytype,'','',this.wintersport,'',this.adventuresport, this.accidents,'','','','',this.motoristaid,'','','');
travelinsurercoverageMdl.filterTravelInsurerCoverage(function(travelinsurercoverage, callback2){
count--;
async.forEach(travelinsurercoverage, function(item2, callback3) {
retValTravelInsurerAndCoverageList.push({
//I have shorted the list below, to
//get a better overview of the code
//travel_insurer
_id: item._id,
name: item.name
//travel_insurercoverage
adventuresport: item2.adventuresport,
accidents: item2.accidents,
cashcoverageextraamount: item2.cashcoverageextraamount
//extra fields
familytype: item.familytype
});
if(count == 0) {
return callback(); //if count is subtracted completely, then the list is finished and can be calledback to the res.send function.
}
}, callback1); //callback to retValTravelInsurerList to get the next item in the array.
});
});
}],
function(err) {
if(err){
return (err);
} else {
res.send(JSON.stringify(retValTravelInsurerAndCoverageList));
}
});
下面是函数filterTravelInsurerCoverage声明,它由内部async.forEach调用。动态where和数组被缩短......
async.series([
function(callback)
{
//define the model
var travelinsurercoverageModel = conn.model('travel_insurercoverages', schema);
//define the query
var query = travelinsurercoverageModel.find();
//build dynamic where
if(utilnull.isItemNullValue(locals._cancellation3000))
{ query.where({'Cancellation3000': {'$gte' : 0}}); }
if(utilnull.isItemNullValue(locals._motoristaid))
{ query.where({'MotoristAid': {'$gte' : 0}}); }
if(utilnull.isItemNullValue(locals._businesstravel))
{ query.where({'BusinessTravel': {'$gte' : 0}}); }
if(utilnull.isItemNullValue(locals._extendedtravelperiod))
{ query.where({'ExtendedTravelPeriod': {'$gte' : 0}}); }
if(utilnull.isItemNullValue(locals._extendedtravelprice))
{ query.where({'ExtendedTravelPrice': {'$gte' : 0}}); }
//execute query
query.exec(function (err, reis) {
if (err) return callback(err);
reis.forEach(function(item) {
retVal.push({
_id: item.id,
insuranceidref: item.InsuranceIDREF,
familytype: item.FamilyType,
basepriceeurope: item.BasePriceEurope,
businesstravel: item.BusinessTravel,
extendedtravelperiod: item.ExtendedTravelPeriod,
extendedtravelprice: item.ExtendedTravelPrice
});
});
callback();
})
}
],
function(err)
{
if(err){
return err;
}
else {
callback(retVal);
}
}
);
答案 0 :(得分:1)
问题似乎与您的回调处理有关。
async.forEach的使用方式如下:
async.forEach(array, function(item, next) {
// do stuff with item, which comes from the array
next();
// ALWAYS invoke next(). If you have an error and need to stop the processing, pass an error argument
}, function(err) {
// end callback, invoked when all item where processed, of when an error is reported
});
forEach
将并行处理您的资料。如果您需要停止它们,请错误地调用next
,并且将调用您的结束回调,而不会触发其他未处理的项目。
您永远不应该使用return
,抛出错误或从父作用域调用另一个回调来破坏此工作流。
---编辑 -
例如,你可以这样:
function(callback) {
async.forEach(retValTravelInsurerList, function(item, next1) {
travelinsurercoverageMdl.constructorTravelInsurerCoverage('', item._id, item.familytype,'','',this.wintersport,'',this.adventuresport, this.accidents,'','','','',this.motoristaid,'','','');
// here is an asynchronous processing: next1 will be invoked when it ends
travelinsurercoverageMdl.filterTravelInsurerCoverage(function(travelinsurercoverage, callback2){
async.forEach(travelinsurercoverage, function(item2, next2) {
retValTravelInsurerAndCoverageList.push({
//I have shorted the list below, to
//get a better overview of the code
//travel_insurer
_id: item._id,
name: item.name
//travel_insurercoverage
adventuresport: item2.adventuresport,
accidents: item2.accidents,
cashcoverageextraamount: item2.cashcoverageextraamount
//extra fields
familytype: item.familytype
});
// item2 processing is finished: let nested async.forEach knows about it
next2();
}, next1); // when all item2 in travelinsurercoverage are processed, let first async.forEach knows about it
}, callback); // when all item in retValTravelInsurerList are processed, your overall processing is ok.