Reputation: 1374
I found: Correct way to write loops for promise. and While loop using bluebird promises
However when I try to use these to loop a promise, the resolve value of that promise is not passed down the chain.
For example, the following code prints:
did it 1 times
did it 2 times
undefined <-- this should be hello world
var Promise = require('bluebird');
var times = 0;
var do_it = function(o) {
return new Promise(function(resolve, reject) {
setTimeout(function () {
console.log("did it %d times", ++times);
resolve(o);
}, 1000);
});
}
var promiseWhile = Promise.method(function(condition, action) {
if (!condition()) return;
return action().then(promiseWhile.bind(null, condition, action));
});
var do_it_twice = function(o) {
return promiseWhile(
function() { return times < 2; },
function() { return do_it(o); }
);
}
do_it_twice("hello world").then(function(o) {console.log(o)});
Upvotes: 0
Views: 2858
Reputation: 1267
I recently had a problem similar to this problem and came across this question. I ended up using an asynchronous recursive function to loop the request until a condition was met. In my case I had to check the length of an array attribute of the response (it was scraped data and a script on the page would sometimes not load the data before sending a response). Here was my solution, which sends another request if the response contained no articles (it is vanilla ES6 and allows you to use any condition (I used out.data.length===0)):
export async function scrape () {
let out = await axios.get('/api/scrape');
if(out.data.articles.length===0){
return await scrape();
}
else return out;
}
Upvotes: 1
Reputation: 12033
You need to specify returned value
var promiseWhile = Promise.method(function(condition, action, result) {
if (!condition()) return result;
return action().then(promiseWhile.bind(null, condition, action, result));
});
var do_it_twice = function(o) {
return promiseWhile(
function() { return times < 2; },
function() { return do_it(o); },
o
);
}
Upvotes: 3