Emma Hannah Emma Hannah - 3 years ago 67
Javascript Question

Javascript for loop not waiting for all promise to execute

I was having some problem with asynchronous call and for loop. What I am facing now is the for loop never waits for all the promise to complete before execute another round. My code skeleton as such:

for(let count = 0; count < 10; count++){

// random select category from list

// random select merchant
let randomMerchantName = new Promise((resolve, reject) => {
merchantName = branchlist[branchIndex].merchantName;
resolve(merchantName);
});

// create merchant
// check if merchant exists before add
let promiseMerchantKey = new Promise((resolve, reject) => {
randomMerchantName.then((merchantName) => {
firebase.database().ref('merchants').orderByChild('merchantName').equalTo(merchantName).once('value', function(snapshot) {
var merchantData = snapshot.val();
if (merchantData){
console.log('merchant exists');
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
resolve(item.key);
});
}else{
var merchantKey = firebase.database().ref('merchants').push({
merchantName : merchantName
}).getKey();

resolve(merchantKey);
}
});
});
});

// all other promises to insert record into different child

}


Is there any way to do this such that the for loop will wait for all my promises done executing before executing another round? Thanks in advanced!

EDIT

// touchable onclick execute this
populate = () => {
promiseNameList.then((namelist) => {
this.loopCounter(1, 10, namelist);
});
}

loopCounter = (index, maxIndex, namelist) => {
// all promises and code to insert to firebase

// last promise here
promiseReceiptKey.then((receiptKey) => {
this.loopCounter(index, 10, namelist);
});
}

Answer Source

You can also do it in a function that calls it self:

function ramdomMerch (index, maxIndex) {
  count = index;
  count++;
  if (count > maxIndex) {
    exit(); //This will end the loop as soon as it hits the maxIndex
  }


  // random select merchant
  let randomMerchantName = new Promise((resolve, reject) => {
      merchantName = branchlist[branchIndex].merchantName;
      resolve(merchantName);
  });


            let promiseMerchantKey = new Promise((resolve, reject) => {
              randomMerchantName.then((merchantName) => {
                firebase.database().ref('merchants').orderByChild('merchantName').equalTo(merchantName).once('value', function(snapshot) {
                  var merchantData = snapshot.val();
                    if (merchantData){
                      console.log('merchant exists');
                      snapshot.forEach(function(childSnapshot) {
                        var item = childSnapshot.val();
                        item.key = childSnapshot.key;
                        resolve(item.key);
                      });
                    }else{
                      var merchantKey = firebase.database().ref('merchants').push({
                        merchantName : merchantName
                      }).getKey();

                      resolve(merchantKey);
                    }
                    ramdomMerch(count, maxIndex); // Here we simply call after finish the next "loop"
                });
              });
            });
}

randomMerch(1, 10); //We start it like an loop with the start and endIndex

A better way to work with promises is the then operator. It would be a syntax like:

let promiseMerchantKey = new Promise(( ... 
promiseMerchantKey.then(function(value) {
   // Sucess, call next promise or next loop if it was the last
  }, function(reason) {
  // error
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download