Danish Woman
Danish Woman

Reputation: 151

Loop with nested promise

What is the best way to get result from a promise inside a For loop. In this example code resultArray is not complete when the loops ends.

  var resultArr = [];
  var itemArray1 = [1, 2, 3, 4, 5];
  var itemArray2 = ['a','b','c','d','e'];
  for (var a = 0; a < itemArray1.length; a++) {
      for (var b = 0; b < itemArray2.length; b++) {
          myPromise(a,b)
          .then(function(result) {
                if (result != null) {
                    resultArr.push(result);
                }
          });

      }
  }  

  // resultArray is still not complete


 function myPromise(a,b) {
     return new Promise(function(resolve, reject) {
         // request to mongodb
         myTable.findOne({ _id:a, name:b }, function(err,result) {
             if (err) throw err;
             resolve(result);
         });
     });
 } 

Upvotes: 1

Views: 2358

Answers (2)

JLRishe
JLRishe

Reputation: 101652

In my opinion, the cleanest way to do things like this is to use Promise.all() with Array#map. Also, make sure to give keep your functions clean and concise, and give them meaningful names!

var itemArray1 = [1, 2, 3, 4, 5];
var itemArray2 = ['a','b','c','d','e'];

function flatten(arrays) {
    return [].concat(arrays);
}

function queryAs() {
    return Promise.all(itemArray1.map(queryBs))
        // the result is an array of arrays, so we'll flatten them here
        .then(flatten);
}

function queryBs(a) {
    return Promise.all(itemArray2.map(function (b) {
        return performQuery(a, b);
    }));
}

// resultArray is still not complete
function performQuery(a, b) {
    return new Promise(function(resolve, reject) {
        // request to mongodb
        myTable.findOne({ _id:a, name:b }, function(err,result) {
            if (err) throw err;
            resolve(result);
        });
    });
}

queryAs().then(function (results) {
    console.log(results);
});

Upvotes: 1

user5383152
user5383152

Reputation:

You could use a combination of forEach and Promise.all

var resultArr = [];
var itemArray1 = [1, 2, 3, 4, 5];
var itemArray2 = ['a', 'b', 'c', 'd', 'e'];

var myPromise = (item1, item2) => new Promise((resolve, reject) => {
    myTable.findOne({
        _id: item1,
        name: item2
    }, function(err, result) {
        if (err) reject(err);
        else resolve(result);
    });
});

var promises = [];
itemArray1.forEach(item1 => {
    itemArray2.forEach(item2 => {
        promises.push(myPromise(item1, item2));
    });
});

Promise.all(promises).then(result => {
    console.log(result);
}).catch(err => {
    console.error(err.message);
});

Upvotes: 1

Related Questions