dmx
dmx

Reputation: 1990

Javascript - How to handle promises correctly with loops?

I am using promises to handle list of task:

This is a sample of code:

var array = ["aaa", "bbbb", "cccc", "dddd", "eeee"];
var result = [];
var p = Promise.resolve({ 
  then: function(onFulfill, onReject) { 
   array.forEach(function(x){
     // http request with x and make sure this request ends before a new one if fired
     // put http resolte in array : result.push(httpRespose); 
   });
   //when done, onFulfill(result) 
}
});
p.then(
function(v) {
    console.log(v); // "fulfilled!"
  }, function(e) {
      console.log(e); // not called
});

I want to be able to make and http request using every element from array, then put result in an other array and when done return that new array. I also want to know if it is possible to make sure that http results are added in the same order (it is not very important).

Can someone please help ?

Upvotes: 0

Views: 87

Answers (2)

Thomas
Thomas

Reputation: 12637

To "run promises" in sequence (especially from an Array) you can use this pattern:

var donePromise = arrayOfData.reduce(function(sequence, value, index){
    return sequence.then(function(){
        //doSomethingWithValueAndReturnAPromise
    })
}, Promise.resolve());

but since you want the results accumulated, and not only an indicator when the job is done, we need to modufy this:

We're using Array.map() and Promise.all() to accumulate the results, and a similar approach as above to ensure the sequential execution:

var urls = [/*...*/];

var _sequence = Promise.resolve();
Promise.all(urls.map(function(url) {
    return _sequence = _sequence.then(function(){
        //fetch the url and return a Promise:  
        //return fetch(url).then(response => response.text())
    });
})).then(function(results){
    //console.log(results)
});

Upvotes: 1

xdumaine
xdumaine

Reputation: 10329

Promise.all is used to wait for a number of promises to fulfill.

Each time you create a promise, push it into an array and then use

Promise.all(myPromiseArray).then(allDoneHandler)

Here's an example:

var items = [ 500, 1000, 1500 ];
var results = [];
items.forEach((item) => {
  let promise = new Promise((resolve) => {
    setTimeout(() => {
        console.log(item);
        resolve(item);
    }, item);
  });
  results.push(promise);
});
Promise.all(results).then(() => {
    console.log('done!');
});
            

Upvotes: 1

Related Questions