【问题标题】:Does window.postMessage guarantee the order of events?window.postMessage 是否保证事件的顺序?
【发布时间】:2011-09-24 03:50:17
【问题描述】:
window.onmessage = ...
window.postMessage('1', '*');
window.postMessage('2', '*');

postMessage (http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#queue-a-task) 是否保证事件的顺序?

【问题讨论】:

    标签: javascript postmessage


    【解决方案1】:

    我不知道,虽然the spec 的措辞似乎暗示它没有做出这样的保证(这令人惊讶)。很明显,一旦在接收端将MessageEvent 添加到task queue,那么它的顺序就会保持,尽管MessageEvent 创建和调度与原始postMessage 调用是异步的,所以理论上看起来你可能有以下情况:

    主线程:

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

    如果线程管理系统允许第二个 postMessage 在第一个线程成功调度 MessageEvent 之前执行,并且无论出于何种不幸的原因允许新线程执行(稀释的优先级反转),再次在第一个线程之前执行设法发送,那么您确实会以相反的顺序收到这些消息。

    虽然规范中可能有其他地方为这些异步执行提供更多上下文并排除了这种情况 - 我找不到它。

    【讨论】:

    • ...逆序吓到我了,如果我使用“postMessage”,我应该考虑这个;
    • @4esn0k,即使它可能发生,我认为这不太可能,因为 (1) 操作系统在几乎所有情况下都会正确地对这些进行时间优先排序,而不是颠倒顺序 (2) 这两条消息会有将在彼此之间非常接近的时间内发布,并且 CPU 在重负载下无法在第二个甚至开始之前完成第一个。实现也有可能以一种顺序安全的方式实现这一点。
    • 我无法使用 window.postMessage 重现反向顺序,但我可以使用 Webkit 浏览器中的 MessageChannel API ... channel.port2.postMessage(...) (实现 MessageChannel 的 Opera 也总是调用听众按正确的顺序)
    • @davin: 知道postMessage() 通知监听器并以任意顺序传递响应,我如何区分这些消息?我想将给定的回复与第一篇文章或第二篇文章相关联。帖子针对相同的来源并形成相同的窗口,但针对不同的 URL。
    • @dma_k:消除这些情况的一种简单方法是将原始 URL 或等效的唯一 ID 与消息捆绑在一起。实际上,我一直在研究更难的情况:从 same URL 中区分两条消息,但在两个不同的 iframe 中打开。除了 window.name 技巧或通过握手消息模式之外,我目前找不到任何方法来做到这一点。理想的情况是,如果每个帧都有一个唯一且可用的 uuid,但由于某种原因没有公开。
    【解决方案2】:

    window.postMessage()仅在被调用时触发消息事件,与经典的事件发布-订阅机制一样,并不能真正保证其顺序的顺序。

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 2020-09-27
      相关资源
      最近更新 更多