21
window.onmessage = ...
window.postMessage('1', '*');
window.postMessage('2', '*');

Does postMessage (http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#queue-a-task) guarantee the order of events?

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
4esn0k
  • 9,789
  • 7
  • 33
  • 40

2 Answers2

13

I don't know, although the wording of the spec seems to suggest it doesn't make such guarantees (which is surprising). It's clear that once the MessageEvent is added to the task queue on the receiving end, then it's order is maintained, although the MessageEvent creation and dispatch are asynchronous to the original postMessage call, so theoretically it appears that you could have the following situation:

main thread:

window.postMessage('1', '*'); --> thread spawned to create MessageEvent
window.postMessage('2', '*'); --> new thread spawned for another MessageEvent

If the thread management system allowed the second postMessage to execute before the first thread managed to dispatch the MessageEvent, and for whatever unlucky reason allowed that newer thread to execute (a diluted priority inversion), again before the first managed to dispatch, then you would indeed receive those messages in the reverse order.

Although there might be some other place in the spec that provides more context for these asynchronous executions and rules out this case - I couldn't find it.

davin
  • 44,863
  • 9
  • 78
  • 78
  • ...reverse order scares me, it meens that i should consider this if i use "postMessage"; – 4esn0k Sep 25 '11 at 13:54
  • @4esn0k, even if it could happen I presume it's very unlikely because (1) The OS on almost all occasions will time-prioritise these correctly and not invert the order (2) The two messages would have to be posted within a *very* close time of each other and the CPU under heavy load to not finish the first before the second even started. It's also possible that implementations implement this in an order-safe way. – davin Sep 25 '11 at 15:12
  • i can't reproduce reverse order with window.postMessage, but i can with MessageChannel API ... channel.port2.postMessage(...) in Webkit Browsers (Opera that implements MessageChannel too always call listeners in right order) – 4esn0k Sep 28 '11 at 06:30
  • @davin: Knowing that `postMessage()` notifies the listener and passed the response in any order, how can I distinguish between such messages? I want to associate a given reply either with first post or with second post. Posts are done for the same origin and form the same window, but for different URLs. – dma_k Sep 20 '13 at 15:42
  • @dma_k: An easy way to disambiguate between those cases is to bundle the origin URL or an equivalent unique ID with the message. I have actually been looking at the harder case: telling apart two messages from the *same* URL but opened in two different iframes. I currently can't find any way to do this other than window.name tricks or through a handshake message pattern. The ideal would be if every frame had a unique and available uuid, but for some reason that is not exposed. – Namey Jan 11 '16 at 08:03
5

window.postMessage() only triggers a message event on being invoked, and as with classic event publish-subscribe mechanism, there is not real guarantee of the order in their order.

Saket
  • 45,521
  • 12
  • 59
  • 79