aboutsummaryrefslogtreecommitdiff
path: root/node_modules/when/poll.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/when/poll.js')
-rw-r--r--node_modules/when/poll.js114
1 files changed, 114 insertions, 0 deletions
diff --git a/node_modules/when/poll.js b/node_modules/when/poll.js
new file mode 100644
index 000000000..10a7d4131
--- /dev/null
+++ b/node_modules/when/poll.js
@@ -0,0 +1,114 @@
+/** @license MIT License (c) copyright 2012-2013 original author or authors */
+
+/**
+ * poll.js
+ *
+ * Helper that polls until cancelled or for a condition to become true.
+ *
+ * @author Scott Andrews
+ */
+
+(function (define) { 'use strict';
+define(function(require) {
+
+ var when = require('./when');
+ var attempt = when['try'];
+ var cancelable = require('./cancelable');
+
+ /**
+ * Periodically execute the task function on the msec delay. The result of
+ * the task may be verified by watching for a condition to become true. The
+ * returned deferred is cancellable if the polling needs to be cancelled
+ * externally before reaching a resolved state.
+ *
+ * The next vote is scheduled after the results of the current vote are
+ * verified and rejected.
+ *
+ * Polling may be terminated by the verifier returning a truthy value,
+ * invoking cancel() on the returned promise, or the task function returning
+ * a rejected promise.
+ *
+ * Usage:
+ *
+ * var count = 0;
+ * function doSomething() { return count++ }
+ *
+ * // poll until cancelled
+ * var p = poll(doSomething, 1000);
+ * ...
+ * p.cancel();
+ *
+ * // poll until condition is met
+ * poll(doSomething, 1000, function(result) { return result > 10 })
+ * .then(function(result) { assert result == 10 });
+ *
+ * // delay first vote
+ * poll(doSomething, 1000, anyFunc, true);
+ *
+ * @param task {Function} function that is executed after every timeout
+ * @param interval {number|Function} timeout in milliseconds
+ * @param [verifier] {Function} function to evaluate the result of the vote.
+ * May return a {Promise} or a {Boolean}. Rejecting the promise or a
+ * falsey value will schedule the next vote.
+ * @param [delayInitialTask] {boolean} if truthy, the first vote is scheduled
+ * instead of immediate
+ *
+ * @returns {Promise}
+ */
+ return function poll(task, interval, verifier, delayInitialTask) {
+ var deferred, canceled, reject;
+
+ canceled = false;
+ deferred = cancelable(when.defer(), function () { canceled = true; });
+ reject = deferred.reject;
+
+ verifier = verifier || function () { return false; };
+
+ if (typeof interval !== 'function') {
+ interval = (function (interval) {
+ return function () { return when().delay(interval); };
+ })(interval);
+ }
+
+ function certify(result) {
+ deferred.resolve(result);
+ }
+
+ function schedule(result) {
+ attempt(interval).then(vote, reject);
+ if (result !== void 0) {
+ deferred.notify(result);
+ }
+ }
+
+ function vote() {
+ if (canceled) { return; }
+ when(task(),
+ function (result) {
+ when(verifier(result),
+ function (verification) {
+ return verification ? certify(result) : schedule(result);
+ },
+ function () { schedule(result); }
+ );
+ },
+ reject
+ );
+ }
+
+ if (delayInitialTask) {
+ schedule();
+ } else {
+ // if task() is blocking, vote will also block
+ vote();
+ }
+
+ // make the promise cancelable
+ deferred.promise = Object.create(deferred.promise);
+ deferred.promise.cancel = deferred.cancel;
+
+ return deferred.promise;
+ };
+
+});
+})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });