1

I am having trouble working out why a promise is being fulfilled when the documentation says it should be rejected.

Open http://jsbin.com/orifok/5/edit and click the go button, and it alerts "ok" when it should alert "fail".

Replace when221.all... with deferred2.promise.then(stepFulfilled, stepRejected); and the rejection occurs.

I did make a modification to the when.js code to make the when221 variable global, rather than needing a dependency upon the require.js library (see http://pastebin.com/J8wCqjWM compared with original https://github.com/cujojs/when/blob/2.2.1/when.js).

when.all() documentatation says: If any of the promises is rejected, the returned promise will be rejected with the rejection reason of the first promise that was rejected - see https://github.com/cujojs/when/blob/master/docs/api.md#whenall

robocat
  • 5,293
  • 48
  • 65

1 Answers1

1

tl;dr: when.all must be passed a promise, not a deferred, and the programmer needs to be very careful to not make that mistake.

Brian Cavalier answered this here: https://github.com/cujojs/when/issues/172 and the modified code is here: http://jsbin.com/orifok/10/edit

The answer is as follows:

Hi, your example code passes deferred objects to when.all. Deferred objects are not promises. Unfortunately, some libraries, such as jQuery, and admittedly, earlier versions of when.js, conflate promises and deferred objects. To try to clarify, I've recently started referring to deferred objects as simply the pair {resolver, promise}. You should pass promises, not deferred objects, to when.all.

Here's a revised version of your example that will work as you expect:

(function(){
var deferred1 = when221.defer();
var deferred2 = when221.defer();

window.clickgo = function() {
  // Pass the promise, not the deferred
  when221.all([deferred1.promise, deferred2.promise]).then(stepFulfilled, stepRejected);
  deferred2.reject('foooo');
};

function stepFulfilled() {
    alert('ok');
}

function stepRejected(failed) {
    alert('failed ' + failed);
}

})();

Note also that when,js >= 2.2.0 also has a new, lighter weight promise creation API when.promise, which I've started recommending over when.defer. They are suited to different situations, but I've found that I prefer it most of the time.

Hope that helps!

robocat
  • 5,293
  • 48
  • 65