diff --git a/src/events.js b/src/events.js index 3b7ddc5988..a9b5d319aa 100644 --- a/src/events.js +++ b/src/events.js @@ -21,16 +21,38 @@ node.EventEmitter.prototype.listeners = function (type) { }; // node.Promise is defined in src/events.cc -var promise = node.Promise.prototype; -promise.addCallback = function (listener) { +node.Promise.prototype.addCallback = function (listener) { this.addListener("success", listener); return this; }; -promise.addErrback = function (listener) { +node.Promise.prototype.addErrback = function (listener) { this.addListener("error", listener); return this; }; +node.Promise.prototype.wait = function () { + var ret; + var had_error = false; + this.addCallback(function () { + if (arguments.length == 1) { + ret = arguments[0]; + } else if (arguments.length > 1) { + ret = []; + for (var i = 0; i < arguments.length; i++) { + ret.push(arguments[i]); + } + } + }) + .addErrback(function (arg) { + had_error = true; + ret = arg; + }) + .block(); + + if (had_error) throw ret; + return ret; +}; + })(); // end anonymous namespace diff --git a/test/mjsunit/test-promise-block.js b/test/mjsunit/test-promise-block.js deleted file mode 100644 index 8773f3ab2c..0000000000 --- a/test/mjsunit/test-promise-block.js +++ /dev/null @@ -1,46 +0,0 @@ -include("mjsunit.js"); - -var p1_done = false; -var p1 = new node.Promise(); -p1.addCallback(function () { - p1_done = true; -}); - -var p2_done = false; -var p2 = new node.Promise(); -p2.addCallback(function () { - p2_done = true; - setTimeout(function () { - p1.emitSuccess(); - }, 100); -}); - -var p3_done = false; -var p3 = new node.Promise(); -p3.addCallback(function () { - p3_done = true; -}); - -function onLoad () { - - p2.emitSuccess(); - - assertFalse(p1_done); - assertTrue(p2_done); - assertFalse(p3_done); - - p1.block() - - assertTrue(p1_done); - assertTrue(p2_done); - assertFalse(p3_done); - - p3.emitSuccess(); -} - - -function onExit() { - assertTrue(p1_done); - assertTrue(p2_done); - assertTrue(p3_done); -} diff --git a/test/mjsunit/test-promise-wait.js b/test/mjsunit/test-promise-wait.js new file mode 100644 index 0000000000..02d7ea32bd --- /dev/null +++ b/test/mjsunit/test-promise-wait.js @@ -0,0 +1,84 @@ +include("mjsunit.js"); + +var p1_done = false; +var p1 = new node.Promise(); +p1.addCallback(function () { + assertEquals(1, arguments.length); + assertEquals("single arg", arguments[0]); + p1_done = true; +}); + +var p2_done = false; +var p2 = new node.Promise(); +p2.addCallback(function () { + p2_done = true; + setTimeout(function () { + p1.emitSuccess(["single arg"]); + }, 100); +}); + +var p3_done = false; +var p3 = new node.Promise(); +p3.addCallback(function () { + p3_done = true; +}); + + + +var p4_done = false; +var p4 = new node.Promise(); +p4.addCallback(function () { + assertEquals(3, arguments.length); + assertEquals("a", arguments[0]); + assertEquals("b", arguments[1]); + assertEquals("c", arguments[2]); + p4_done = true; +}); + +var p5_done = false; +var p5 = new node.Promise(); +p5.addCallback(function () { + p5_done = true; + setTimeout(function () { + p4.emitSuccess(["a","b","c"]); + }, 100); +}); + +function onLoad () { + + p2.emitSuccess(); + + assertFalse(p1_done); + assertTrue(p2_done); + assertFalse(p3_done); + + var ret1 = p1.wait() + assertEquals("single arg", ret1); + + assertTrue(p1_done); + assertTrue(p2_done); + assertFalse(p3_done); + + p3.emitSuccess(); + + assertFalse(p4_done); + assertFalse(p5_done); + + p5.emitSuccess(); + + assertFalse(p4_done); + assertTrue(p5_done); + + var ret4 = p4.wait(); + assertArrayEquals(["a","b","c"], ret4); + + assertTrue(p4_done); +} + +function onExit() { + assertTrue(p1_done); + assertTrue(p2_done); + assertTrue(p3_done); + assertTrue(p4_done); + assertTrue(p5_done); +} diff --git a/website/api.txt b/website/api.txt index 027f07f47a..4bf3fc5550 100644 --- a/website/api.txt +++ b/website/api.txt @@ -158,10 +158,16 @@ 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.block()+ :: ++promise.wait()+ :: Blocks futher execution until the promise emits a success or error event. -Events setup before the call to +promise.block()+ was made may still be -emitted and executed while +promise.block()+ is blocking. +Events setup before the call to +promise.wait()+ was made may still be +emitted and executed while +promise.wait()+ is blocking. ++ +If there was a single argument to the +"success"+ event then it is returned. +If there were multiple arguments to +"success"+ then they are returned as an +array. ++ +If +"error"+ was emitted instead, +wait()+ throws an error. === Standard I/O @@ -409,10 +415,10 @@ node.fs.rename("/tmp/hello", "/tmp/world").addCallback(function () { }); ------------------------------------------------------------------------------ -Or use the +promise.block()+ functionality: +Or use the +promise.wait()+ functionality: ------------------------------------------------------------------------------ -node.fs.rename("/tmp/hello", "/tmp/world").block(); +node.fs.rename("/tmp/hello", "/tmp/world").wait(); node.fs.stat("/tmp/world").addCallback(function (stats) { puts("stats: " + JSON.stringify(stats)); });