Browse Source

The return of Promise.cancel() with some additional tests & docs

v0.7.4-release
Felix Geisendörfer 16 years ago
committed by Ryan Dahl
parent
commit
659954d842
  1. 17
      doc/api.txt
  2. 33
      src/events.js
  3. 49
      test/mjsunit/test-promise-timeout.js

17
doc/api.txt

@ -215,6 +215,7 @@ emit anymore events.
| Event | Parameters | Notes
| +"success"+ | (depends) |
| +"error"+ | (depends) |
| +"cancel"+ | (depends) |
|=========================================================
+promise.addCallback(listener)+ ::
@ -223,6 +224,9 @@ Adds a listener for the +"success"+ event. Returns the same promise object.
+promise.addErrback(listener)+ ::
Adds a listener for the +"error"+ event. Returns the same promise object.
+promise.addCancelback(listener)+ ::
Adds a listener for the +"cancel"+ event. Returns the same promise object.
+promise.emitSuccess(arg1, arg2, ...)+ ::
If you created the promise (by doing +new node.Promise()+) then call
+emitSuccess+ to emit the +"success"+ event with the given arguments.
@ -233,10 +237,21 @@ the moment due to a bug; use +emitSuccess+ instead.)
+promise.emitError(arg1, arg2, ...)+ ::
Emits the +"error"+ event.
+promise.emitCancel(arg1, arg2, ...)+ ::
Emits the +"cancel"+ event. You may still get a +"success"+ or +"error"+
callback if the promise giver does not handle the cancel event. Use
+promise.cancel()+ to ignore any later events.
+promise.cancel()+ ::
Clears all +"success"+ and +"error"+ event listeners from the promise, then
emits the +"cancel"+ event. Whether or not the promise is actually canceled
or not depends on the promise giver. This also clears Promise.timeout() if one
was set.
+promise.timeout(timeout = undefined)+ ::
If the +timeout+ parameter is provided, the promise will emit an +"error"+
event after the given amount of millseconds. The timeout is canceled by any
+"success"+ or +"error"+ event being emitted by the Promise.
+"success"+, +"error"+ or +"cancel"+ event being emitted by the Promise.
+
To tell apart a timeout from a regular "error" event, use the following test:
+

33
src/events.js

@ -30,14 +30,42 @@ node.Promise.prototype.timeout = function(timeout) {
clearTimeout(this._timer);
}
var promiseComplete = false;
var onComplete = function() {
promiseComplete = true;
};
this
.addCallback(onComplete)
.addCancelback(onComplete)
.addErrback(onComplete);
var self = this
this._timer = setTimeout(function() {
if (promiseComplete) {
return;
}
self.emitError(new Error('timeout'));
}, this._timeoutDuration);
return this;
};
node.Promise.prototype.cancel = function() {
this._events['success'] = [];
this._events['error'] = [];
this.emitCancel();
};
node.Promise.prototype.emitCancel = function() {
var args = Array.prototype.slice.call(arguments);
args.unshift('cancel');
this.emit.apply(this, args);
};
node.Promise.prototype.addCallback = function (listener) {
this.addListener("success", listener);
return this;
@ -48,6 +76,11 @@ node.Promise.prototype.addErrback = function (listener) {
return this;
};
node.Promise.prototype.addCancelback = function (listener) {
this.addListener("cancel", listener);
return this;
};
node.Promise.prototype.wait = function () {
var ret;
var had_error = false;

49
test/mjsunit/test-promise-timeout.js

@ -29,6 +29,55 @@ try {
timeouts++;
}
var successPromise = new node.Promise();
successPromise.timeout(500);
setTimeout(function() {
successPromise.emitSuccess();
}, 250);
successPromise.addErrback(function() {
assertUnreachable('addErrback should not fire if there is no timeout');
});
var errorPromise = new node.Promise();
errorPromise.timeout(500);
setTimeout(function() {
errorPromise.emitError(new Error('intentional'));
}, 250);
errorPromise.addErrback(function(e) {
assertInstanceof(e, Error);
assertEquals('intentional', e.message);
});
var cancelPromise = new node.Promise();
cancelPromise.timeout(500);
setTimeout(function() {
cancelPromise.cancel();
}, 250);
setTimeout(function() {
cancelPromise.emitSuccess('should be ignored');
}, 400);
cancelPromise.addCallback(function(e) {
assertUnreachable('addCallback should not fire if the promise is canceled');
});
cancelPromise.addErrback(function(e) {
assertUnreachable('addErrback should not fire if the promise is canceled');
});
var cancelTimeoutPromise = new node.Promise();
cancelTimeoutPromise.timeout(500);
setTimeout(function() {
cancelPromise.emitCancel();
}, 250);
cancelPromise.addErrback(function(e) {
assertUnreachable('addErrback should not fire after a cancel event');
});
process.addListener('exit', function() {
assertEquals(2, timeouts);
});
Loading…
Cancel
Save