Jay Bienvenu Jay Bienvenu - 2 months ago 6
Javascript Question

Javascript: Promise to wait for condition or abort after number of tries

How do I code this algorithm as a promise in JavaScript?

// condition: some situation that is not true
// interval: period to wait before trying again
// retriesAllowed: maximum number of retries to make before aborting
// retriesMade: number of retries made so far
while() {
if (condition) return true; // indicates success
if (retriesMade < retriesAllowed) return false; // or throw an exception
++retriesMade;
wait(interval);
}


This doesn't work, since it doesn't actually wait for the check to resolve to true or false before moving on:

var check = () => {
if (condition) return true; // indicates success
if (retriesMade < retriesAllowed) return false; // or throw an exception
++retriesMade;
setTimeout(check,interval)
}
check();

Answer

This doesn't work, since it doesn't actually wait for the check to resolve to true or false before moving on.

One part of that may be that the fail/exit condition seems to be inversed, so it will probably always exit after the 1st round of checking the condition:

// retriesMade starts at 0, which is likely already less-than retriesAllowed
if (retriesMade < retriesAllowed) return false;

// probably should be
if (retriesMade >= retriesAllowed) return false;

Beyond that, the lack of waiting is by design with asynchronous operations, such as setTimeout() waiting out the given delay interval. Surrounding code will always continue to execute without waiting for their result.

Instead of expecting them to wait, you'll need to establish a way to be informed when the process has actually completed and carry on from that information. Promises are one option for that.

Side note: A thorough explanation of the behavior and other options are provided in "How do I return the response from an asynchronous call?"

With them, in place of using return or throw, they provide resolve() and reject() functions that signal success or failure, respectively, when invoked. Their .then() and .catch() methods can be used to setup continuations.

var tries = new Promise((resolve, reject) => {
    var retriesMade = 0;
    var interval = 1000;

    var check = () => {
        if (condition) { resolve(); }
        if (retriesMade >= retriesAllowed) { reject(); }
        ++retriesMade;
        setTimeout(check, interval);
    });

    check();
});

tries.then(
    () => console.log('success'),
    () => console.log('failure')
);
Comments