jdonaldson / promhx

A promise and functional reactive programming library for Haxe
MIT License
145 stars 24 forks source link

A list of promises can resolve and error at the same time #63

Open alebianco opened 9 years ago

alebianco commented 9 years ago

I call that a quantum promise...

Consider this scenario:

var d1 = new Deferred<Int>();
var d2 = new Deferred<Int>();
var d3 = new Deferred<Int>();

var p1 = d1.promise();
var p2 = d2.promise();
var p3 = d3.promise();

Promise.whenAll([p1, p2, p3])
.then(function(r:Array<Int>) {
    trace('complete $r');
}).catchError(function(e:Dynamic) {
    trace('error $e');
});

Timer.delay(function() {
    d1.resolve(1);
}, 10);

Timer.delay(function() {
    d2.resolve(2);
}, 20);

Timer.delay(function() {
    d3.resolve(3);
    d3.throwError("nope");
}, 5);

it would trace:

complete [1,2,3]
error nope

since the promise resolves before throwing an error, i would expect it to only call the "then" method. Or if it errors first, only call the catchError method.

I guess my assumption could be wrong and this be the intended behaviour but it feels wrong ...

alebianco commented 9 years ago

checking p3.isRejected() and p3.isResolved() they both return true

jdonaldson commented 9 years ago

That's a good illustration of the resolve behavior... Everything is deferred, and errors have priority. However, you can recover from errors and everything gets back on track. However, isResolved should be false in your example. Let me check into that.

alebianco commented 9 years ago

so you say that a promise can error and be rejected after being resolved? it's hard to recover when both methods are invoked in an unspecified order (change the order of the resolve and throwError of d3 and the console output will be inverted)

i would expect that, when after p3 resolves there's an error, the promise group should fail as a whole. what feels wrong is that it resolves and also fails when all promises are completed ... maybe i'm completely wrong, i should go read a book about promises :confounded:

jdonaldson commented 9 years ago

I added in deferred.throwError as a universal way of tripping error logic for asyncs like promise and streams. It's pretty low level. I don't understand how/why you are handling a promise twice (by rejecting and resolving it, presumably in two different locations). But, I agree I'll probably need to handle this case.

alebianco commented 9 years ago

That was a minimal scenario to demonstrate the behaviour, this gist is closer to my current situation https://gist.github.com/alebianco/15a52b27460369e75115#file-main-hx-L45 i didn't expect that error to be caught by the previous promise error handler