dfilatov / vow

ES6-compatible and Promises/A+ implementation for Node.js and browsers
MIT License
344 stars 45 forks source link

Chaining Vow.Promise methods (then, fail) works strangely #64

Closed edoroshenko closed 10 years ago

edoroshenko commented 10 years ago

If I chain calls of method then like this

var promise = new Vow.Promise();
promise.then(onSuccess1).then(onSuccess2);
promise.fulfill();

both onSuccess1 and onSuccess2 are called. And it's an expected behaviour. If I chain calls of method fail like this

promise.fail(onError1).fail(onError2);
promise.reject();

or do something like this

promise.then(onSuccess, onError1).fail(onError2);
promise.reject();

then only onError1 is called. And it's an unexpected behaviour. This hurts, when you return Vow.Promise from function. You can't write something like this

var magic = function() {
  ...
  return promise.fail(function() {
    ...
  });
}

magic().fail(function() {
  ...
})

So, while chaining works expectedly only for method then, you should not use chaining at all to prevent remembering complicated rules.

dfilatov commented 10 years ago

If you need to propagate error through chain, you should either throw exception from onError handler or return rejected promise. Otherwise it's assumed that onError handler has processed error.

See specification: https://github.com/promises-aplus/promises-spec

edoroshenko commented 10 years ago

So, am I correct, if I say, that i shouldn't want to chain calls of promise methods?

dfilatov commented 10 years ago

No, you aren't.

promise
    .fail(function(e) {
        ...
        throw e; // or return vow.reject(e);
    })
    .fail(function(e) {
        // this callback will be invoked
    });
edoroshenko commented 10 years ago

If I want to chain fail calls, I must throw an exception in each of them. True?

dfilatov commented 10 years ago

Yes, you should propagate error in each callback if you need. The point is that you can handle error and turn chain to the success case.

edoroshenko commented 10 years ago

ok, understood. Thanks!