0

I have a for loop that inserts documents in MongoDB. Using async series I run the loop five times then close the connection. For some strange reason I get an insert error when the loop is executed for the sixth time. I am just not sure what is happening here. Any ideas?

var mycollection= "abcd";
var count = 5;
var db;
var col;

async.series([
 // Connect to DB
 function(callback) {
  MongoClient.connect("mongodb://connection-path-here",function(error, db2) {
      if (error) {console.log("db connect error");callback(error,"db connect error"); return;} 
      db = db2;
      callback(null,"connect success");
  });
},
function(callback) {
  col = db.collection(mycollection);
  callback(null,"collection success");
},
function(callback) {
  console.log ("insert begin ...");               
  for (var i = 1; i <= count; i++) {
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
    });
  }
callback(null,"insert success");
},
function (callback){
  console.log ("close db");db.close();
  callback(null,"connection closed");
}
], function(error, results) {
    if (error) { console.log("error"); }
        console.log(results);
});

output

insert begin ...
inserting .....1
inserting .....2
inserting .....3
inserting .....4
inserting .....5
close db
insert error:6
error
  [ 'connect success', 'collection success', 'insert error' ]
insert error:6
insert error:6
insert error:6
insert error:6

2 Answers 2

1

You started well but you are mixing async and non-async methods here:

function(callback) {
  console.log ("insert begin ...");               
  for (var i = 1; i <= count; i++) {
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
    });
  }
callback(null,"insert success");
},

This does not wait for the insert to complete before iterating the next loop, so you need something that waits. Try "async.whilst":

function(callback) {
    var i = 1;
    async.whilst(
        function() { return i <= count },
        function(callback) {
            col.insert({ c: i },function(error,result) {
                if (error)
                    console.log("insert error:" + i);
                i++;
                callback(error);
            });
        },
        function(error) {
          callback(error,"insert sucess")
        }
    );
},

The rest can proceed as you are doing and the results will be sent to the end of the series execution.

Sign up to request clarification or add additional context in comments.

Comments

0

All of your async operations should be a function in the "operations" array that you are executing. Your for loop calls col.insert() 6 times but before the 6th operation can complete you are calling callback(null, "insert success") - this will cause a race condition so sometimes it may actually make it all the way through or maybe it will only insert a couple of records depending on how long each insert takes.

See the modified code below to fix the issue:

var mycollection= "abcd";
var count = 5;
var db;
var col;

// create operations array with first two operations
var operations = [
  // Connect to DB
   function(callback) {
    MongoClient.connect("mongodb://connection-path-here",function(error, db2) {
        if (error) {console.log("db connect error");callback(error,"db connect error"); return;} 
        db = db2;
        callback(null,"connect success");
    });
  },
  function(callback) {
    col = db.collection(mycollection);
    callback(null,"collection success");
  }
];


// push each insert into operations as its own individual operation
for (var i = 1; i <= count; i++) {
  operations.push(function(callback){
    console.log("inserting ....." + i);
    col.insert({c:i}, function(error,result) {
        if (error) {console.log("insert error:" + i);callback(error,"insert error"); return;}
        // no errors here, so this insert was successful!
        callback(null);
    });
  })
}

// finish pushing the last two operations
operations.push(function(callback) {
  callback(null,"insert success");
});

operations.push(function (callback){
  console.log ("close db");db.close();
  callback(null,"connection closed");
});

// execute all the operations
async.series(operations, function(error, results) {
  if (error) { console.log("error"); }
  console.log(results);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.