mpen
mpen

Reputation: 283203

Is this Promise chain guaranteed to execute in this order?

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let p = sleep(50);

p.then(() => console.log('a')).then(() => console.log('c'));
p.then(() => console.log('b')).then(() => console.log('d'));

Is this guaranteed to print "a, b, c, d" in that order?

As far as I can tell, "a" has to fire before "c" and "b" has to fire before "d", but beyond that, can the JS interpreter decide to execute the remainder in a different order?

Upvotes: 6

Views: 369

Answers (2)

Bergi
Bergi

Reputation: 665256

As far as I can tell, "a" has to fire before "c" and "b" has to fire before "d"

Yes, that much for certan.

beyond that, can the JS interpreter decide to execute the remainder in a different order?

Depends on whom you ask, but no there are more guarantees that make the output more predictable:

  • the Promise/A+ specification also demands that "all respective callbacks must execute in the order of their originating calls to then." So in your example, that means "a" has to fire before "b", because the callback was chained first to p.
  • the ECMAScript specification defines a job queue for promise callbacks, nailing down the order (imo unnecessarily). It conforms to Promises/A+ in that the "a" and "b" callbacks are queued in the order they were set up when the promise fulfills. It also means that after "a" returns and fulfills the promise, it will schedule "c", and after "b" returns and fulfills the promise, it will schedule "d", so their order is determined as well (for synchronous callbacks).

In general, don't rely on any scheduling algorithm, if you require a certain order then make it explicit.

Upvotes: 1

The Dembinski
The Dembinski

Reputation: 1519

The way that things are queued using setTimeout is exactly that - a queue. If two callbacks are queued with the same 'delay', the callback that was queued first, will fire first.

Edit: I failed to understand the OP's intention initially.

'Branching' promises is what is actually occurring here. Meaning - the 'then-able' being referenced in the first set of then-ables (for a & b) will fire the two provided callbacks at 'the same time' because they both reference the same promise - however - the tricky bit is that they execute in the order that they were queued using the .then(...) of the resolving promise object.

Then the following/subsequent callbacks are queued in their respective orders (c & d).

To answer the question directly: No. The nature of the async actions in a then-able could be anything. However, the functions provided in the OP's then-ables are essentially synchronous, resulting in the intuitive - but entirely misleading - logging order.

Upvotes: 1

Related Questions