A+ doesn't require that you use the browser's asynchronous scheduling mechanism, it only requires that the promise callback is always executed
after the current function. There is a really neat hack to achieve this without completely relying on the browser's scheduler by implementing your own callback queue.
asap(callback);
which will push to an array of callbacks that you need to execute and then call a loop if one isn't currently active:
function asap(cb) {
callbacks.push(cb);
setTimeout(flushQueue, 5);
}
Flushqueue will run all the callbacks from the queue in a loop, then empty it
function flushqueue() {
if (flushing) return;
flushing = true;
for (var k = 0; k < callbacks.length; ++k) {
callbacks[k]();
}
flushing = false;
}
Now if some of the callbacks schedules a new function to execute using asap
promise.then(function first(x) { return alreadyResolvedPromise.then(function second(y) { return y.some.property; }); });
then when "promise" resolves, first()'s execution will push a new function to the queue, changing queue.length, causing that loop above to cause one more iteration - but only after first is complete.
(If you don't nest the callbacks, then the push will happen before flushqueue even starts executing)
The code above is overly simplified but I think its enough to demonstrate the idea. (Huge thanks Stefan Penner for explaining it to me :D)