Blame view

node_modules/when/poll.js 3.1 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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 work function on the msec delay. The result of
  	 * the work 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 work 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 work {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 [delayInitialWork] {boolean} if truthy, the first vote is scheduled
  	 *     instead of immediate
  	 *
  	 * @returns {Promise}
  	 */
  	return function poll(work, interval, verifier, delayInitialWork) {
  		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(work(),
  				function (result) {
  					when(verifier(result),
  						function (verification) {
  							return verification ? certify(result) : schedule(result);
  						},
  						function () { schedule(result); }
  					);
  				},
  				reject
  			);
  		}
  
  		if (delayInitialWork) {
  			schedule();
  		} else {
  			// if work() 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); });