Rafa Romero
Rafa Romero

Reputation: 2716

asyncjs callback not being executed

I'm trying to merge the data from two JSON files (customer list) and then, create as many task as customers there are to be executed later via async.js

In order to have all the tasks array full, I'm controlling the end of the forEach with a promise:

var parsePromise = new Promise(function (resolve, reject) {
mongoDB.MongoClient.connect(dbURL, (error, db) => {
        originalData.forEach(function (element, index) {
            var restoredCustomer = Object.assign(element, backupData[index]);

            tasksArray.push((function (db, element) {
                return function () {
                    db.collection('customers').insert(element, function (error) {
                        if (error) {
                            console.error("Error: ", error);
                        }
                    })
                }
            })(db, restoredCustomer));

            forEachCounter--;
            if (forEachCounter === 0) {
                resolve(tasksArray);
            }
        });
    });
});

Then, when the promise ends, I execute the async.js parallel method:

parsePromise.then(function (tasksArray) {
    async.parallel(tasksArray, (err, results) => {
        console.log("Operation completed successfully: ", results);
    })
})

The weird thing is that the code is working fine, and the inserts are being done on MongoDB, however, the console.log("Operation completed successfully: ", results); placed in the parallel callback is never shown.

Upvotes: 0

Views: 104

Answers (1)

Daniel Jee
Daniel Jee

Reputation: 664

Try this

var parsePromise = new Promise(function (resolve, reject) {
mongoDB.MongoClient.connect(dbURL, (error, db) => {
        originalData.forEach(function (element, index) {
            var restoredCustomer = Object.assign(element, backupData[index]);
             tasksArray.push(function(cb){
                  db.collection('customers').insert(restoredCustomer, function (error) {
                        if (error) return cb(err);
                        cb();
                    })
             });

            forEachCounter--;
            if (forEachCounter === 0) {
                resolve(tasksArray);
            }
        });
    });
});

According to async js documentation https://caolan.github.io/async/global.html tasks arguments in parallel function in async.js must be AsyncFunction. AsyncFunction requires to have the final parameter which is a callback. The structure of the callback follows the standard of function(err, args).

Also you can try simplifying your code to:

new Promise((resolve, reject) => {
  mongoDB.MongoClient.connect(dbURL, (error, db) => {
        if (error) return reject(error);
        resolve(db);
  });
}).then(db => {
  var tasksArray = [];
  for (let i = 0; i != originalData.length; ++i){
    var restoredCustomer = Object.assign(originalData[i], backupData[index]);
    tasksArray.push(function(cb){
      db.collection('customers').insert(restoredCustomer, function (error) {
        if (error) return cb(err);
        cb();
      })
    });
  }

  return new Promise((resolve, reject) => {
    async.parallel(tasksArray, (err, results) => {
        if (err) return reject(err);
        resolve(results)
    })
  })
})

Upvotes: 1

Related Questions