代码之家  ›  专栏  ›  技术社区  ›  user3374131

NodeJS POST保持挂起状态

  •  0
  • user3374131  · 技术社区  · 11 年前

    我用jQuery向NodeJS后端发布了一个json字符串,在后端处理post数据时遇到了问题。后端似乎在某处受阻,但我找不到位置。因此,我的POSTS将状态保持为待定状态,有时会返回200。

    我下面的代码使用async.forEach retValTravelInsurerList循环,这是一个由23个保险公司组成的数组。我有一个嵌套的async.forEach,它用值设置构造函数,并在filterTravelInsurerOverage中执行查询。这意味着23个查询通过Mongoose(MongoDB)数据库执行。

    如果在filterTravelInsurerOverage数组中找到retValTravelInsureerList中的项目,我只需要这些项目,并且我将填充一个新的数组(retValTravelInsurerAndCoverageList),其中存储了所有需要的项目。

    如果旅行保险公司承保范围包含retValTravelInsurerList=>假设23。

    但是,如果生成的数组(retValTravelInsurerAndCoverageList)长度小于(travelinsurercoverage)长度,则会发生POST问题,如果我向服务器发布几次,则Chrome的javascript控制台中的状态保持为“待定”。

    在我看来,NodeJS调用堆栈中仍然有一些项,即使在返回callback()时也会阻止未来的POSTS;被调用。

    有人知道如何解决这个问题吗?

    顺便说一句:我使用异步库,在返回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));
      }
    });
    

    下面是声明的函数filterTravelInsurerOverage,它由内部async.forEach调用。。。

       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);
            }
        }
        );
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   Feugy    11 年前

    问题似乎来自回调处理。

    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.