Browse Source

Remove Promise.prototype.wait()

I don't want users to have to think about coroutine safety.

http://thread.gmane.org/gmane.comp.lang.javascript.nodejs/2468/focus=2603
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
764783560e
  1. 66
      src/node.js
  2. 3
      test/mjsunit/disabled/test-eio-race3.js
  3. 11
      test/mjsunit/test-promise-timeout.js
  4. 98
      test/mjsunit/test-promise-wait.js
  5. 32
      test/mjsunit/test-wait-ordering.js

66
src/node.js

@ -281,72 +281,6 @@ var eventsModule = createInternalModule('events', function (exports) {
return this.addListener("error", listener); return this.addListener("error", listener);
}; };
/* Poor Man's coroutines */
var coroutineStack = [];
exports.Promise.prototype._destack = function () {
this._blocking = false;
while (coroutineStack.length > 0 &&
!coroutineStack[coroutineStack.length-1]._blocking)
{
coroutineStack.pop();
process.unloop("one");
}
};
exports.Promise.prototype.wait = function () {
var self = this;
var ret;
var hadError = false;
if (this.hasFired) {
ret = (this._values.length == 1)
? this._values[0]
: this.values;
if (this.hasFired == 'success') {
return ret;
} else if (this.hasFired == 'error') {
throw ret;
}
}
self.addCallback(function () {
if (arguments.length == 1) {
ret = arguments[0];
} else if (arguments.length > 1) {
ret = Array.prototype.slice.call(arguments);
}
self._destack();
});
self.addErrback(function (arg) {
hadError = true;
ret = arg;
self._destack();
});
coroutineStack.push(self);
if (coroutineStack.length > 10) {
process.stdio.writeError("WARNING: promise.wait() is being called too often.\n");
}
self._blocking = true;
process.loop();
process.assert(self._blocking == false);
if (hadError) {
if (ret) {
throw ret;
} else {
throw new Error("Promise completed with error (No arguments given.)");
}
}
return ret;
};
}); });
var events = eventsModule.exports; var events = eventsModule.exports;

3
test/mjsunit/test-eio-race3.js → test/mjsunit/disabled/test-eio-race3.js

@ -1,5 +1,8 @@
/* XXX Can this test be modified to not call the now-removed wait()? */
process.mixin(require("./common")); process.mixin(require("./common"));
puts('first stat ...'); puts('first stat ...');
fs.stat(__filename) fs.stat(__filename)

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

@ -21,15 +21,6 @@ setTimeout(function() {
promise.emitSuccess('Am I too late?'); promise.emitSuccess('Am I too late?');
}, 500); }, 500);
var waitPromise = new events.Promise();
try {
waitPromise.timeout(250).wait()
} catch (e) {
assert.equal(true, e instanceof Error);
assert.equal('timeout', e.message);
timeouts++;
}
var successPromise = new events.Promise(); var successPromise = new events.Promise();
successPromise.timeout(500); successPromise.timeout(500);
setTimeout(function() { setTimeout(function() {
@ -52,5 +43,5 @@ errorPromise.addErrback(function(e) {
}); });
process.addListener('exit', function() { process.addListener('exit', function() {
assert.equal(2, timeouts); assert.equal(1, timeouts);
}); });

98
test/mjsunit/test-promise-wait.js

@ -1,98 +0,0 @@
process.mixin(require("./common"));
events = require('events');
var p1_done = false;
var p1 = new events.Promise();
p1.addCallback(function () {
assert.equal(1, arguments.length);
assert.equal("single arg", arguments[0]);
p1_done = true;
});
var p2_done = false;
var p2 = new events.Promise();
p2.addCallback(function () {
p2_done = true;
setTimeout(function () {
p1.emitSuccess("single arg");
}, 100);
});
var p3_done = false;
var p3 = new events.Promise();
p3.addCallback(function () {
p3_done = true;
});
var p4_done = false;
var p4 = new events.Promise();
p4.addCallback(function () {
assert.equal(3, arguments.length);
assert.equal("a", arguments[0]);
assert.equal("b", arguments[1]);
assert.equal("c", arguments[2]);
p4_done = true;
});
var p5_done = false;
var p5 = new events.Promise();
p5.addCallback(function () {
p5_done = true;
setTimeout(function () {
p4.emitSuccess("a","b","c");
}, 100);
});
var p6 = new events.Promise();
var p7 = new events.Promise();
p7.addErrback(function() {});
p2.emitSuccess();
assert.equal(false, p1_done);
assert.equal(true, p2_done);
assert.equal(false, p3_done);
var ret1 = p1.wait()
assert.equal("single arg", ret1);
assert.equal(true, p1_done);
assert.equal(true, p2_done);
assert.equal(false, p3_done);
p3.emitSuccess();
assert.equal(false, p4_done);
assert.equal(false, p5_done);
p5.emitSuccess();
assert.equal(false, p4_done);
assert.equal(true, p5_done);
var ret4 = p4.wait();
assert.deepEqual(["a","b","c"], ret4);
assert.equal(true, p4_done);
p6.emitSuccess("something");
assert.equal("something", p6.wait());
p7.emitError("argh!");
var goterr;
try {
p7.wait();
} catch(err) {
goterr = err;
}
assert.equal("argh!", goterr.toString());
process.addListener("exit", function () {
assert.equal(true, p1_done);
assert.equal(true, p2_done);
assert.equal(true, p3_done);
assert.equal(true, p4_done);
assert.equal(true, p5_done);
});

32
test/mjsunit/test-wait-ordering.js

@ -1,32 +0,0 @@
process.mixin(require("./common"));
var events = require('events');
function timer (t) {
var promise = new events.Promise();
setTimeout(function () {
promise.emitSuccess();
}, t);
return promise;
}
order = 0;
var a = new Date();
function test_timeout_order(delay, desired_order) {
delay *= 10;
timer(0).addCallback(function() {
timer(delay).wait()
var b = new Date();
assert.equal(true, b - a >= delay);
order++;
// A stronger assertion would be that the ordering is correct.
// With Poor Man's coroutines we cannot guarentee that.
// Replacing wait() with actual coroutines would solve that issue.
// assert.equal(desired_order, order);
});
}
test_timeout_order(10, 6); // Why does this have the proper order??
test_timeout_order(5, 5);
test_timeout_order(4, 4);
test_timeout_order(3, 3);
test_timeout_order(2, 2);
test_timeout_order(1, 1);
Loading…
Cancel
Save