Permalink
Browse files

#24 - Candidate fix to make cancelable deferred invoke progress callback

  • Loading branch information...
1 parent d7d4338 commit dc1f0ba2d717e14a8b9c8388d8ba3a222f71bb12 @briancavalier briancavalier committed Mar 13, 2012
Showing with 51 additions and 13 deletions.
  1. +23 −13 cancelable.js
  2. +14 −0 test/cancelable.js
  3. +14 −0 test/promise.js
View
@@ -16,7 +16,7 @@
*/
(function(define) {
-define(function() {
+define(['./when'], function(when) {
// private flag to indicate that a rejection is actually a cancel
var canceled = {};
@@ -34,30 +34,40 @@ define(function() {
*/
return function(deferred, canceler) {
- // Add a cancel method to the deferred
+ // Add a cancel method to the deferred to reject the original
+ // with the special canceled indicator.
deferred.cancel = function() {
deferred.reject(canceled);
};
- // Replace deferred's promise with a promise that will always call canceler() first, *if*
- // deferred is canceled. Can now safely give out deferred.promise
- deferred.promise = deferred.then(null,
- function cancelHandler(e) {
- throw e === canceled ? canceler(deferred) : e;
- });
+ // Setup a rejection handler that will run before all others to
+ // detect the canceled indicator and run the provided canceler
+ // function if necessary.
+ function cancelHandler(e) {
+ d.reject(e === canceled ? canceler(deferred) : e);
+ }
- // Replace deferred.then to allow it to be called safely and observe the cancellation
- deferred.then = deferred.promise.then;
+ // Replace deferred's promise with a promise that will always call canceler() first,
+ // *if* deferred is canceled. Can now safely give out deferred.promise
+ var d = when.defer();
+
+ deferred.then(d.resolve, cancelHandler, d.progress);
+
+ deferred.promise = d.promise;
+
+ // Also replace deferred.then to allow it to be called safely and
+ // observe the cancellation
+ deferred.then = d.promise.then;
return deferred;
};
});
})(typeof define == 'function'
? define
- : function (factory) { typeof module != 'undefined'
- ? (module.exports = factory())
- : (this.when_cancelable = factory());
+ : function (deps, factory) { typeof module != 'undefined'
+ ? (module.exports = factory(require('./when')))
+ : (this.when_cancelable = factory(this.when));
}
// Boilerplate for AMD, Node, and browser global
);
View
@@ -54,8 +54,22 @@ buster.testCase('when/cancelable', {
done();
}
);
+ },
+
+ 'should call progback for cancellable deferred': function(done) {
+ var expected, c;
+
+ expected = {};
+ c = cancelable(when.defer());
+ c.then(null, null, function (status) {
+ assert.same(status, expected);
+ done();
+ });
+
+ c.progress(expected);
}
+
});
})(
View
@@ -290,6 +290,20 @@ buster.testCase('promise', {
);
d.reject(1);
+ },
+
+ 'should call progback': function(done) {
+ var expected, d;
+
+ expected = {};
+ d = when.defer();
+
+ d.promise.then(null, null, function (status) {
+ assert.same(status, expected);
+ done();
+ });
+
+ d.progress(expected);
}
});

0 comments on commit dc1f0ba

Please sign in to comment.