0

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)});
4
  • 1
    if (!condition()) return; - change that to if (!condition()) return 'oops'; ... what happens now? Commented Feb 8, 2016 at 11:33
  • Thanks. That was it. Commented Feb 8, 2016 at 11:38
  • really? that doesn't solve the problem, that shows you what you are doing wrong! Commented Feb 8, 2016 at 11:40
  • Yes. That's what I meant. Commented Feb 8, 2016 at 11:45

2 Answers 2

3

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
    );
}
Sign up to request clarification or add additional context in comments.

Comments

1

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;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.