dfilatov/vow

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

Closed this issue · 6 comments

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.

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

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

No, you aren't.

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

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

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.

ok, understood. Thanks!