diff --git a/doc/api.txt b/doc/api.txt index e79f904a8f..08ac938a88 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -275,101 +275,6 @@ manipulated, e.g. to remove listeners. +emitter.emit(event, arg1, arg2, ...)+ :: Execute each of the listeners in order with the supplied arguments. -=== +events.Promise+ - -+require("events")+ to access the events module. - -+events.Promise+ inherits from +process.EventEmitter+. A promise emits one of two -events: +"success"+ or +"error"+. After emitting its event, it will not -emit anymore events. - -[cols="1,2,10",options="header"] -|========================================================= -| Event | Parameters | Notes -| +"success"+ | (depends) | -| +"error"+ | (depends) | -|========================================================= - -+promise.addCallback(listener)+ :: -Adds a listener for the +"success"+ event. Returns the same promise object. -The listener is executed right away if the promise has already fired. - -+promise.addErrback(listener)+ :: -Adds a listener for the +"error"+ event. Returns the same promise object. -The listener is executed right away if the promise has already fired. - -+promise.emitSuccess(arg1, arg2, ...)+ :: -If you created the promise (by doing +new events.Promise()+) then call -+emitSuccess+ to emit the +"success"+ event with the given arguments. -+ -(+promise.emit("success", arg1, arg2, ...)+ should also work, but doesn't at -the moment due to a bug; use +emitSuccess+ instead.) - -+promise.emitError(arg1, arg2, ...)+ :: -Emits the +"error"+ event. If no error handler is attached to the promise -between +promise.emitError()+ and +process.nextTick()+, an exception is -thrown. -+ -To explain the exception behavior, assume you have a "computeQuestion" -function as follows: -+ ----------------------------------------- -var events = require('events'); -function computeQuestion(answer) { - var promise = new events.Promise(); - if (answer !== 42) { - promise.emitError('wrong answer'); - return promise; - } - // compute the question for 42 - - return promise; -} ----------------------------------------- -+ -You can stop an exception to be thrown here by attaching an errback handler -right away (in the same event loop tick) like this: -+ ----------------------------------------- -computeQuestion(23).addErrback(function() { - // No exception will be thrown -}); ----------------------------------------- -+ -However, if you try to attach the error handler in a later tick, the promise -will already have thrown an exception: -+ ----------------------------------------- -var promise = computeQuestion(23); -setTimeout(function() { - promise.addErrback(function() { - // This will never execute, - // the promise already threw an exception - }); -}, 1000); ----------------------------------------- - -+promise.timeout(timeout = undefined)+ :: -If the +timeout+ parameter is provided, the promise will emit an +"error"+ -event after the given amount of milliseconds. The timeout is canceled by any -+"success"+ or +"error"+ event being emitted by the promise. -+ -To tell a timeout apart from a regular "error" event, use the following test: -+ ----------------------------------------- -promise.addErrback(function(e) { - if (e instanceof Error && e.message === "timeout") { - // handle timeout - } else { - // handle regular error - } -}); ----------------------------------------- -+ -If the +timeout+ parameter is not provided, the current timeout value, if any, -is returned. - - == Standard I/O diff --git a/src/node.js b/src/node.js index 0615a82cbb..7b5aac012b 100644 --- a/src/node.js +++ b/src/node.js @@ -195,91 +195,6 @@ var eventsModule = createInternalModule('events', function (exports) { if (!this._events.hasOwnProperty(type)) this._events[type] = []; return this._events[type]; }; - - exports.Promise = function () { - exports.EventEmitter.call(this); - this._blocking = false; - this.hasFired = false; - this._values = undefined; - }; - process.inherits(exports.Promise, exports.EventEmitter); - - process.Promise = exports.Promise; - - exports.Promise.prototype.timeout = function(timeout) { - if (!timeout) { - return this._timeoutDuration; - } - - this._timeoutDuration = timeout; - - if (this.hasFired) return; - this._clearTimeout(); - - var self = this; - this._timer = setTimeout(function() { - self._timer = null; - if (self.hasFired) { - return; - } - - self.emitError(new Error('timeout')); - }, timeout); - - return this; - }; - - exports.Promise.prototype._clearTimeout = function() { - if (!this._timer) return; - - clearTimeout(this._timer); - this._timer = null; - } - - exports.Promise.prototype.emitSuccess = function() { - if (this.hasFired) return; - this.hasFired = 'success'; - this._clearTimeout(); - - this._values = Array.prototype.slice.call(arguments); - this.emit.apply(this, ['success'].concat(this._values)); - }; - - exports.Promise.prototype.emitError = function() { - if (this.hasFired) return; - this.hasFired = 'error'; - this._clearTimeout(); - - this._values = Array.prototype.slice.call(arguments); - this.emit.apply(this, ['error'].concat(this._values)); - - if (this.listeners('error').length == 0) { - var self = this; - process.nextTick(function() { - if (self.listeners('error').length == 0) { - throw (self._values[0] instanceof Error) - ? self._values[0] - : new Error('Unhandled emitError: '+JSON.stringify(self._values)); - } - }); - } - }; - - exports.Promise.prototype.addCallback = function (listener) { - if (this.hasFired === 'success') { - listener.apply(this, this._values); - } - - return this.addListener("success", listener); - }; - - exports.Promise.prototype.addErrback = function (listener) { - if (this.hasFired === 'error') { - listener.apply(this, this._values); - } - - return this.addListener("error", listener); - }; }); var events = eventsModule.exports; diff --git a/test/mjsunit/test-promise-timeout.js b/test/mjsunit/test-promise-timeout.js deleted file mode 100644 index dc66247941..0000000000 --- a/test/mjsunit/test-promise-timeout.js +++ /dev/null @@ -1,47 +0,0 @@ -process.mixin(require("./common")); -events = require('events'); - -var timeouts = 0; - -var promise = new events.Promise(); -promise.timeout(250); -assert.equal(250, promise.timeout()); - -promise.addCallback(function() { - assert.ok(false, 'addCallback should not fire after a promise error'); -}); - -promise.addErrback(function(e) { - assert.equal(true, e instanceof Error); - assert.equal('timeout', e.message); - timeouts++; -}); - -setTimeout(function() { - promise.emitSuccess('Am I too late?'); -}, 500); - -var successPromise = new events.Promise(); -successPromise.timeout(500); -setTimeout(function() { - successPromise.emitSuccess(); -}, 250); - -successPromise.addErrback(function() { - assert.ok(false, 'addErrback should not fire if there is no timeout'); -}); - -var errorPromise = new events.Promise(); -errorPromise.timeout(500); -setTimeout(function() { - errorPromise.emitError(new Error('intentional')); -}, 250); - -errorPromise.addErrback(function(e) { - assert.equal(true, e instanceof Error); - assert.equal('intentional', e.message); -}); - -process.addListener('exit', function() { - assert.equal(1, timeouts); -}); diff --git a/test/mjsunit/test-promise.js b/test/mjsunit/test-promise.js deleted file mode 100644 index 149c07e2a0..0000000000 --- a/test/mjsunit/test-promise.js +++ /dev/null @@ -1,79 +0,0 @@ -process.mixin(require('./common')); -var - Promise = require('events').Promise, - - TEST_VALUE = {some: 'object'}, - - expectedCallbacks = { - a1: 1, - a2: 1, - b1: 1, - b2: 1, - c1: 1, - d1: 1, - }; - -// Test regular & late callback binding -var a = new Promise(); -a.addCallback(function(value) { - assert.equal(TEST_VALUE, value); - expectedCallbacks.a1--; -}); -a.addErrback(function(error) { - assert.notEqual(TEST_VALUE, error, 'normal'); -}); -a.emitSuccess(TEST_VALUE); - -assert.ok(a.addCallback(function(value) { - assert.equal(TEST_VALUE, value); - expectedCallbacks.a2--; -})); -assert.ok(a.addErrback(function(error) { - assert.notEqual(TEST_VALUE, error, 'late'); -})); - -// Test regular & late errback binding -var b = new Promise(); -b.addErrback(function(value) { - assert.equal(TEST_VALUE, value); - expectedCallbacks.b1--; -}); -b.emitError(TEST_VALUE); - -b.addErrback(function(value) { - assert.equal(TEST_VALUE, value); - expectedCallbacks.b2--; -}); - -// Test late errback binding -var c = new Promise(); -c.emitError(TEST_VALUE); -assert.ok(c.addErrback(function(value) { - assert.equal(TEST_VALUE, value); - expectedCallbacks.c1--; -})); - -// Test errback exceptions -var d = new Promise(); -d.emitError(TEST_VALUE); - -process.addListener('uncaughtException', function(e) { - if (e.name === "AssertionError") { - throw e; - } - - expectedCallbacks.d1--; - assert.ok(e.message.match(/unhandled emitError/i)); -}); - -process.addListener('exit', function() { - for (var name in expectedCallbacks) { - var count = expectedCallbacks[name]; - - assert.equal( - 0, - count, - 'Callback '+name+' fire count off by: '+count - ); - } -}); \ No newline at end of file