]>
git.wh0rd.org - tt-rss.git/blob - lib/dojo/Deferred.js.uncompressed.js
1 define("dojo/Deferred", [
4 "./errors/CancelError",
6 "./promise/instrumentation"
7 ], function(has
, lang
, CancelError
, Promise
, instrumentation
){
16 var FULFILLED_ERROR_MESSAGE
= "This deferred has already been fulfilled.";
18 var freezeObject
= Object
.freeze
|| function(){};
20 var signalWaiting = function(waiting
, type
, result
, rejection
, deferred
){
22 if(type
=== REJECTED
&& Deferred
.instrumentRejected
&& waiting
.length
=== 0){
23 Deferred
.instrumentRejected(result
, false, rejection
, deferred
);
27 for(var i
= 0; i
< waiting
.length
; i
++){
28 signalListener(waiting
[i
], type
, result
, rejection
);
32 var signalListener = function(listener
, type
, result
, rejection
){
33 var func
= listener
[type
];
34 var deferred
= listener
.deferred
;
37 var newResult
= func(result
);
38 if(type
=== PROGRESS
){
39 if(typeof newResult
!== "undefined"){
40 signalDeferred(deferred
, type
, newResult
);
43 if(newResult
&& typeof newResult
.then
=== "function"){
44 listener
.cancel
= newResult
.cancel
;
46 // Only make resolvers if they're actually going to be used
47 makeDeferredSignaler(deferred
, RESOLVED
),
48 makeDeferredSignaler(deferred
, REJECTED
),
49 makeDeferredSignaler(deferred
, PROGRESS
));
52 signalDeferred(deferred
, RESOLVED
, newResult
);
55 signalDeferred(deferred
, REJECTED
, error
);
58 signalDeferred(deferred
, type
, result
);
62 if(type
=== REJECTED
&& Deferred
.instrumentRejected
){
63 Deferred
.instrumentRejected(result
, !!func
, rejection
, deferred
.promise
);
68 var makeDeferredSignaler = function(deferred
, type
){
69 return function(value
){
70 signalDeferred(deferred
, type
, value
);
74 var signalDeferred = function(deferred
, type
, result
){
75 if(!deferred
.isCanceled()){
78 deferred
.progress(result
);
81 deferred
.resolve(result
);
84 deferred
.reject(result
);
90 var Deferred = function(canceler
){
92 // Creates a new deferred. This API is preferred over
93 // `dojo/_base/Deferred`.
95 // Creates a new deferred, as an abstraction over (primarily)
96 // asynchronous operations. The deferred is the private interface
97 // that should not be returned to calling code. That's what the
98 // `promise` is for. See `dojo/promise/Promise`.
99 // canceler: Function?
100 // Will be invoked if the deferred is canceled. The canceler
101 // receives the reason the deferred was canceled as its argument.
102 // The deferred is rejected with its return value, or a new
103 // `dojo/errors/CancelError` instance.
105 // promise: dojo/promise/Promise
106 // The public promise object that clients can add callbacks to.
107 var promise
= this.promise
= new Promise();
110 var fulfilled
, result
, rejection
;
111 var canceled
= false;
114 if( 1 && Error
.captureStackTrace
){
115 Error
.captureStackTrace(deferred
, Deferred
);
116 Error
.captureStackTrace(promise
, Deferred
);
119 this.isResolved
= promise
.isResolved = function(){
121 // Checks whether the deferred has been resolved.
124 return fulfilled
=== RESOLVED
;
127 this.isRejected
= promise
.isRejected = function(){
129 // Checks whether the deferred has been rejected.
132 return fulfilled
=== REJECTED
;
135 this.isFulfilled
= promise
.isFulfilled = function(){
137 // Checks whether the deferred has been resolved or rejected.
143 this.isCanceled
= promise
.isCanceled = function(){
145 // Checks whether the deferred has been canceled.
151 this.progress = function(update
, strict
){
153 // Emit a progress update on the deferred.
155 // Emit a progress update on the deferred. Progress updates
156 // can be used to communicate updates about the asynchronous
157 // operation before it has finished.
159 // The progress update. Passed to progbacks.
161 // If strict, will throw an error if the deferred has already
162 // been fulfilled and consequently no progress can be emitted.
163 // returns: dojo/promise/Promise
164 // Returns the original promise for the deferred.
167 signalWaiting(waiting
, PROGRESS
, update
, null, deferred
);
169 }else if(strict
=== true){
170 throw new Error(FULFILLED_ERROR_MESSAGE
);
176 this.resolve = function(value
, strict
){
178 // Resolve the deferred.
180 // Resolve the deferred, putting it in a success state.
182 // The result of the deferred. Passed to callbacks.
184 // If strict, will throw an error if the deferred has already
185 // been fulfilled and consequently cannot be resolved.
186 // returns: dojo/promise/Promise
187 // Returns the original promise for the deferred.
190 // Set fulfilled, store value. After signaling waiting listeners unset
192 signalWaiting(waiting
, fulfilled
= RESOLVED
, result
= value
, null, deferred
);
195 }else if(strict
=== true){
196 throw new Error(FULFILLED_ERROR_MESSAGE
);
202 var reject
= this.reject = function(error
, strict
){
204 // Reject the deferred.
206 // Reject the deferred, putting it in an error state.
208 // The error result of the deferred. Passed to errbacks.
210 // If strict, will throw an error if the deferred has already
211 // been fulfilled and consequently cannot be rejected.
212 // returns: dojo/promise/Promise
213 // Returns the original promise for the deferred.
216 if( 1 && Error
.captureStackTrace
){
217 Error
.captureStackTrace(rejection
= {}, reject
);
219 signalWaiting(waiting
, fulfilled
= REJECTED
, result
= error
, rejection
, deferred
);
222 }else if(strict
=== true){
223 throw new Error(FULFILLED_ERROR_MESSAGE
);
229 this.then
= promise
.then = function(callback
, errback
, progback
){
231 // Add new callbacks to the deferred.
233 // Add new callbacks to the deferred. Callbacks can be added
234 // before or after the deferred is fulfilled.
235 // callback: Function?
236 // Callback to be invoked when the promise is resolved.
237 // Receives the resolution value.
238 // errback: Function?
239 // Callback to be invoked when the promise is rejected.
240 // Receives the rejection error.
241 // progback: Function?
242 // Callback to be invoked when the promise emits a progress
243 // update. Receives the progress update.
244 // returns: dojo/promise/Promise
245 // Returns a new promise for the result of the callback(s).
246 // This can be used for chaining many asynchronous operations.
248 var listener
= [progback
, callback
, errback
];
249 // Ensure we cancel the promise we're waiting for, or if callback/errback
250 // have returned a promise, cancel that one.
251 listener
.cancel
= promise
.cancel
;
252 listener
.deferred
= new Deferred(function(reason
){
253 // Check whether cancel is really available, returned promises are not
254 // required to expose `cancel`
255 return listener
.cancel
&& listener
.cancel(reason
);
257 if(fulfilled
&& !waiting
){
258 signalListener(listener
, fulfilled
, result
, rejection
);
260 waiting
.push(listener
);
262 return listener
.deferred
.promise
;
265 this.cancel
= promise
.cancel = function(reason
, strict
){
267 // Inform the deferred it may cancel its asynchronous operation.
269 // Inform the deferred it may cancel its asynchronous operation.
270 // The deferred's (optional) canceler is invoked and the
271 // deferred will be left in a rejected state. Can affect other
272 // promises that originate with the same deferred.
274 // A message that may be sent to the deferred's canceler,
275 // explaining why it's being canceled.
277 // If strict, will throw an error if the deferred has already
278 // been fulfilled and consequently cannot be canceled.
280 // Returns the rejection reason if the deferred was canceled
284 // Cancel can be called even after the deferred is fulfilled
286 var returnedReason
= canceler(reason
);
287 reason
= typeof returnedReason
=== "undefined" ? reason
: returnedReason
;
291 // Allow canceler to provide its own reason, but fall back to a CancelError
292 if(typeof reason
=== "undefined"){
293 reason
= new CancelError();
297 }else if(fulfilled
=== REJECTED
&& result
=== reason
){
300 }else if(strict
=== true){
301 throw new Error(FULFILLED_ERROR_MESSAGE
);
305 freezeObject(promise
);
308 Deferred
.prototype.toString = function(){
310 // Returns `[object Deferred]`.
312 return "[object Deferred]";
316 instrumentation(Deferred
);