Search code examples
node.jsasync.jsknex.js

Nodejs async overwriting values with knex


I am trying to save multiple records in database using async but I always end up in one record overwriting others.

Here is my logic:

var deferred = q.defer();

var records = [{emp_id:1, got_bonus: true},{emp_id:2, got_bonus: false},{emp_id:3, got_bonus: true}];

async.each(records, function(record, next){
    saveRecord(record)
      .then(){
          next(null);
      });
}, function(){
    deferred.resolve();
});

function saveRecord(record){
   record['activity_type'] = 'bonus'; 
   db_module.save(record);
}

db_module.js
----------------
function saveRecord(record){
   var deferred = q.defer();

   checkDuplicate(record)
      .then(function(isDuplicate)){
          if(!isDuplicate){
              knex('employees').insert(record);

              deferred.resolve();
          }
      });
   }
}

function checkDuplicate(record){
   return knex('employees')
            .where({'emp_id': record['emp_id']})
            .then(function(rows){
                return rows && rows.length > 0;
            });
}

My problem is that even using async, the code is not waiting for first record to save and then saves next. The result of above code in database table is:

emp_id      got_bonus
-------     ----------
3            true
3            false
3            true

expected output is:

emp_id      got_bonus
-------     ----------
1            true
2            false
3            true

I tried to use async.waterfall but received the same error. I don't know how to use synchronize module.


Solution

  • I solved this problem by changing async.each to async.eachSeries like this:

    async.eachSeries(records, function(record, next){
      saveRecord(record)
        .then(){
          next(null);
        });
    }, function(){
       deferred.resolve();
    });
    

    eachSeries is same as each but runs only a single async operation at a time.