Skip to content

Instantly share code, notes, and snippets.

@wpm
Last active November 14, 2019 09:59
Show Gist options
  • Save wpm/f745ea6478507c6eb72f to your computer and use it in GitHub Desktop.
Save wpm/f745ea6478507c6eb72f to your computer and use it in GitHub Desktop.
Javascript Polling with Promises
var Promise = require('bluebird');
/**
* Periodically poll a signal function until either it returns true or a timeout is reached.
*
* @param signal function that returns true when the polled operation is complete
* @param interval time interval between polls in milliseconds
* @param timeout period of time before giving up on polling
* @returns true if the signal function returned true, false if the operation timed out
*/
function poll(signal, interval, timeout) {
function pollRecursive() {
return signal() ? Promise.resolve(true) : Promise.delay(interval).then(pollRecursive);
}
return pollRecursive()
.cancellable()
.timeout(timeout)
.catch(Promise.TimeoutError, Promise.CancellationError, function () {
return false;
});
}
/**
* Every 2 seconds, call a signal function that returns true 25% of the time. Timeout after 10 seconds.
*/
poll(randomSignal, 2000, 10000).then(console.log);
function randomSignal() {
var r = Math.random() <= 0.25;
console.log(r ? "Complete" : "Not complete");
return r;
}
@jopek
Copy link

jopek commented Nov 18, 2016

.cancellable() doesn't exist anymore. so the timeout does not have any breaking effect.
how does one exit the polling after timeout?

@ihi-es-analyzer
Copy link

@jopek, I ran into the same issue! What is the preferred way of making a polling function with promises now?

@formula1
Copy link

module.exports.pollUntil = function(fn, delay){
  var notCanceled = true;
  function pollRecursive(){
    return Promise.resolve().then(fn).then((boo)=>(
      notCanceled && boo && new Promise((res)=>(setTimeout(res, delay)))
      .then(pollRecursive)
    ));
  }

  var p = pollRecursive();
  p.cancel = ()=>(
    notCanceled = false
  );
};

@ujwal-setlur
Copy link

@formula1, thanks for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment