123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /** @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); });
|