async.each中的Async.parallel无法正常工作

时间:2017-02-21 11:14:01

标签: node.js mongoose

我有对象数组,即用户,我在async.each中使用async.parallel。现在,我没有在async.each中得到回复。我的代码如下:

exports.addUserByCSV = function (req, res) {


  var users = req.body;
  async.each(users,
    function (user, callback) {
      var user = new User({
        username: user.email,
        password: user.email.split('@')[0],
        ipAddress: req.ip,
        firstname: user.firstname,
        lastname: user.lastname,
        email: user.email,
        employeeCode: user.employeeCode,
        dateOfJoining: user.dateOfJoining,
        dateOfAnniversary: user.dateOfAnniversary,
        dateOfBirth: user.dateOfBirth,
        employeeStatus: user.employeeStatus,
        iw: user.iw,
        fatherName: user.fatherName,
        aliasName: user.aliasName,
        aliasEmail: user.aliasEmail,
        panNo: user.panNo,
        gender: user.gender,
        maritalStatus: user.maritalStatus,
        biometricId: user.biometricId,
        shift: user.shift,
        nextApprisalDate: user.nextApprisalDate,
        esiNo: user.esiNo,
        pfNo: user.pfNo,
        bankAccNo: user.bankAccNo,
        situtation: user.situtation,
        phone: user.phone,
        mobile: user.mobile,
        fax: user.fax,
        website: user.website,
        address: user.address,
        city: user.city,
        state: user.state,
        zip: user.zip,
        country: user.country
      });
      userAdd(user, function (err, user) {
        console.log(user)
        callback(err);
      });
    },
    function (err) {
      res.send({ error: err, message: config.msg.SUCCESSFULLY_ADDED, user: 'User create Successfully' });
    }
  );
  function userAdd(user) {
    //console.log(user)
    user.register(user, function (err, user) {
      async.parallel({

        leave: function (callback) {
          //add some leaves for user
          _availLeaves(req.ID, user._id, function (err, leaves) {
            callback(err, leaves);
          });
        },
        salary: function (callback) {
          //add salary structure for employee
          _salaryStructure(req.ID, user._id, function (err, structure) {
            callback(err, structure);
          });
        }
      }, function (err, results) {
        console.log(results)
        if (!err) { return results; }

        res.send({ error: err, message: config.msg.SUCCESSFULLY_ADDED, user: 'User create Successfully' });

      });

    });
  }

}

function _salaryStructure(loginId, userId, cb) {
  var structure = new Structure({
    userId: userId,
    addedBy: loginId,
  });
  structure.save(function (err, structure) {
    cb(err, structure);
  });
}
function _availLeaves(loginId, userId, cb) {
  var leave = new LeaveAvailable({
    "userId": userId,
    "bl": 0.50,
    "fl": 2,
    "cl": 1,
    "pl": (new Date().getDate() <= 15) ? 0.75 : 0
  });

  leave.save(function (err, leaves) {
    cb(err, 'leavesAdded')
  });
}

如果我在res.send中写async.parallel,那么我会遇到以下问题:

Error: Can't set headers after they are sent.

如果我在res.send中写async.each,那么我没有得到任何回复。

2 个答案:

答案 0 :(得分:0)

问题是,您为每个用户调用了res.send,因此多次。相反,您可以将res.write (每次)res.end 组合(在所有用户都已写完后)

有关详细信息,请查看this

因此,您更新的代码可能如下所示:

exports.addUserByCSV = function(req, res) {


    var users=req.body;
    async.each(users,

  function(user, callback){
     var user = new User({
        username: user.email,
        password: user.email.split('@')[0],
        ipAddress: req.ip,
        firstname: user.firstname,
        lastname: user.lastname,
        email: user.email,
        employeeCode: user.employeeCode,
        dateOfJoining:user.dateOfJoining,
        dateOfAnniversary:user.dateOfAnniversary,
        dateOfBirth:user.dateOfBirth,
        employeeStatus: user.employeeStatus,
        iw: user.iw,
        fatherName:user.fatherName,
        aliasName:user.aliasName,
        aliasEmail:user.aliasEmail,
        panNo:user.panNo,
        gender:user.gender,
        maritalStatus:user.maritalStatus,
        biometricId:user.biometricId,
        shift:user.shift,
        nextApprisalDate:user.nextApprisalDate,
        esiNo:user.esiNo,
        pfNo:user.pfNo,
        bankAccNo:user.bankAccNo,
        situtation:user.situtation,
        phone: user.phone,
        mobile: user.mobile,
        fax: user.fax,
        website: user.website,
        address: user.address,
        city: user.city,
        state: user.state,
        zip: user.zip,
        country: user.country
    }); 

    userAdd(user,function(err,user){  
                console.log(user)
               callback(err);
            });



  },

  function(err){
     if (!err)
        res.end();
     //TODO: Handle error

  }
);
function userAdd(user){
    //console.log(user)
    user.register(user, function(err, user) {
            async.parallel({

                leave:function(callback){
                    //add some leaves for user
                    _availLeaves(req.ID,user._id,function(err,leaves){
                          callback(err,leaves);  
                    });
                },
                salary:function(callback){
                    //add salary structure for employee
                    _salaryStructure(req.ID,user._id,function(err,structure){
                        callback(err,structure);
                    });
                }
            }, function(err, results) {       
                console.log(results)     
               if(!err){return results;}

                res.write(JSON.stringify({error: err,message:config.msg.SUCCESSFULLY_ADDED,user:'User create Successfully'}));

            });

    });
}

    }

    function _salaryStructure(loginId,userId,cb){
        var structure = new Structure({
            userId: userId,
            addedBy: loginId,
        });
        structure.save(function(err,structure){
            cb(err,structure);
        });        
    }
    function _availLeaves(loginId,userId,cb){
        var leave = new LeaveAvailable({
            "userId":userId,
            "bl" : 0.50,
            "fl" : 2,    
            "cl" : 1,  
            "pl" : (new Date().getDate()<=15)?0.75:0
        });

        leave.save(function(err,leaves){
            cb(err,'leavesAdded')
        }); 
    }

答案 1 :(得分:0)

这是一个复杂的代码 - 当然不是重现问题的最小例子 - 所以让我给你一个一般的解释,你可以用它来追踪和解决你的问题。

async.parallelasync.each非常不同。

使用parallel并行运行一组函数。使用each,您可以将单个iteratee函数应用于集合中的每个元素,也可以并行。

在每种情况下,您都需要确保每个函数在某个时刻(错误或成功)调用其回调,否则整个操作将无法完成。

现在,在每次操作完成后,您需要调用res.send()方法一次

E.g。如果你有这样的事情:

async.each(collection, (element, cb) => {
    // you should not return response here
}, err => {
    // you should return response here
});

无论你在上面的iteratee函数中有什么,

都是如此

请参阅: