0

I am trying to figure out how to resolve an arbitrary number of promises one after another within a for-loop.

I have a function called scrapePage(num) that takes in a number and makes an HTTP call to a certain web-page. I have tried out a number of approaches to this problem.

1) Use an array of promises (that resolves them in random order):

var promises = [];
   for (var i = 0; i < 4; i++) {
   promises.push(scrapPage(i));
}
$q.all(promises).then(doMoreThings);

2) Use a chain of calls (that is useless for an arbitrary number of calls):

var chain = $q.when();
chain.then(function() {
    return scrapPage(0);
}).then(function() {
    return scrapPage(1);
}).then(function() {
    return scrapPage(2);
}).then(function() {
    return scrapPage(3);
}).then(doMoreThings);

I was playing around with the chain function, trying to get it to work. For testing purposes, I made scrapePage print out "page #n" every time it resolves.

Here's what I have right now:

var chain = $q.when();
for (var i = 0; i < 4; i++) {
    console.log("i: " + i);
    chain = chain.then(function() {
        console.log("\ni: " + i);
        return scrapPage(i);
    });                 
}    

I can point out two major problems it has.

First, its output is absolutely weird.

i: 0
i: 1
i: 2
i: 3

i: 4
page #4

i: 4
page #4

i: 4
page #4

i: 4
page #4

Second, I don't know how to make it doMoreThings after all promises are resolved.

Could anyone tell me what I'm missing?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
rutilum
  • 3
  • 1

1 Answers1

0

Try changing var to let.

var chain = $q.when();
for (let i = 0; i < 4; i++) {
    console.log("i: " + i);
    chain = chain.then(function() {
        console.log("\ni: " + i);
        return scrapPage(i);
    });                 
}

That would probably solve the first problem.

For the second one, you could add a condition like this:

if (i == 4){
    doMoreThings();
}
else {
    return scrapPage(i);
}

instead of just return scrapPage(i);

holydragon
  • 6,158
  • 6
  • 39
  • 62