【问题标题】:Use transferable objects with a shared worker将可转移对象与共享工作者一起使用
【发布时间】:2015-12-09 11:43:24
【问题描述】:

在我的共享工作者中使用可转移对象时,我在主线程中收到null for event.data。经过一番搜索,我找到了this post,其中解释了ArrayBuffer 在通过MessagePort 的MessageChannel 时总是丢失。

共享工作者通信也使用端口和消息通道完成。这是否意味着无法在SharedWorker 实例中使用可转移对象?或者有什么解决办法?

我需要将一个巨大的string 从SharedWorkerGlobalScope 传输回主线程。想法是将其转换为ArrayBuffer,如this example 所示,然后传输缓冲区。据说这比发送字符串要快得多...

发送数据:

var arrayBuffer = convertStringToArrayBuffer( string );

var data = {
    message: "here is an array buffer",
    arrayBuffer: arrayBuffer 
};

port.postMessage(data, [data.arrayBuffer]);

接收数据:

worker.port.onmessage = function( event ) {

    // data is null
    var data = event.data;

}

【问题讨论】:

    标签: javascript web-worker transferable shared-worker message-channel


    【解决方案1】:

    只需使用postMessage,无需转让。无论如何,字符串是不可转移的(所以它总是被复制的)。

    拥有可转让的目标是在将对象从发送方传递到接收方时成本最低。这样的消息可以跨越进程边界,并且进行进程间通信是昂贵的。这是the reason why transferables are not supported yet with MessagePort。顺便说一句,跨进程通信困难也是Safari dropped support for SharedWorkers的原因。

    【讨论】:

    • 感谢您查看我的问题。我知道字符串不可转让,但我可以轻松地将其转换为ArrayBuffer,如示例here 所示。然后我可以发送ArrayBuffer。这适用于巨大的字符串(甚至可能是 100Mb),据说比发送没有可传输的消息要快得多。
    • @Wilt 即使 transferables 按预期工作,那么您的方法也不会节省任何性能(理论上)。您只需在源线程中分配缓冲区,然后将缓冲区传递到目标,而不是在目标中分配新缓冲区。但是 Chrome 不支持可转让(由于我的回答中给出的原因),因此您不太可能找到具有所需性能特征的解决方法。因此,您可以只为简单起见,而不要使用可转让物品。
    • 好的。感谢您的回答。我会考虑一个不可转让的解决方案......能够测试这个并亲眼看看我是否可以获得一些性能提升,这似乎很好。
    • @Wilt 你真的需要共享工作者吗? Transferables 在普通的 Web 工作者中工作得很好,所以除非有充分的理由使用 SharedWorkers,否则我只会使用普通的工作者。更进一步:你真的需要工人吗?如果例如字符串是网络请求的结果,那么从主线程发送请求同样有效。
    • 我们需要工人。该字符串是密集解析过程的结果。我们的 UI 曾经在解析过程中完全冻结。我们现在使用 SharedWorkers,因此我们可以同时使用多个 worker 解析一个巨大的队列。使用 WebWorkers 时我们的性能得到了极大的提升,并且我们的 UI 在解析过程中是响应式的。所以一切都很好......
    猜你喜欢
    • 2015-05-07
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2017-02-16
    相关资源
    最近更新 更多