Browse Source

Remove promises

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
0485cc41d5
  1. 95
      doc/api.txt
  2. 85
      src/node.js
  3. 47
      test/mjsunit/test-promise-timeout.js
  4. 79
      test/mjsunit/test-promise.js

95
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

85
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;

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

@ -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);
});

79
test/mjsunit/test-promise.js

@ -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
);
}
});
Loading…
Cancel
Save