fastWhen looks like:
function fastWhen(promise, callback) {
if (Q.isFulfilled(promise)) {
return callback(null, Q.nearer(promise));
} else {
return promise.then(function (value) {
return callback(null, value);
}, function (err) {
return callback(err);
});
}
}
The two key problems with doing that in the main library are that:
a) A function could sometimes be called sooner than expected because it could get called syncronously:
function go() {
var res = getAsyncValue().then(function (foo) {
return foo + bar;
});
var bar = 'bar';
return res;
}
If you call that with then implemented using then it is safe, because bar will always be declared before the then callback is called. With fastWhen it could get called too soon, so that would be a bad time to use fastWhen.
Using QJS you might try and write:
var go = async(function () {
var res = yield(getAsyncValue()) + bar;
var bar = 'bar';
return res;
});
This won't work with fastWhen or normal When because bar won't have been declared before you attempt to use it, but that's obvious and expected from reading the code. You'd need to refactor it to:
var go = async(function () {
var bar = 'bar';
var res = yield(getAsyncValue()) + bar;
return res;
});
Which works fine with fastWhen.
b) It could cause stack overflow if you keep yielding on lots of already resolved promises:
This is a little trickier to reason about, fastWhen, as implemented above won't work properly, because it will add a layer or two to the stack each time you yield on an already resolved promises. This is only a problem when you have a lot of iterations though, and it can actually be fixed by more subtly including the behaviour of fastWhen in the implementation of Async such that it doesn't add any layers to the stack when a promise is already resolved.
If there are other problems with asap/fastWhen then let me know, as I don't want to be sacrificing safety for performance.