Eri*_*rik 16 javascript html5 web-worker html5-filesystem
有没有办法在Web worker和主线程之间传递大量数据(多个MB)?我在一个项目中工作,我需要下载文件,稍微修改它们,然后以某种方式让用户下载修改后的文件.我找到了以下方法在Web worker和主UI之间传递数据
postMessage方法.我认为(1)在发送较小的对象时很好,但是处理大于几MB的文件需要花费大量的时间和空间,因为它被序列化并作为JSON发送.Chrome提供了一种使用可转移对象传输数据的方法,其中不必复制数据.不幸的是,到目前为止,这只是Chrome的一项功能,因为它本来可以达到我的目的.
我发现的最后一件事是,从工作人员创建一个使用blob的URL self.webkitURL,然后只将URL引用传递给UI.这很好用,我可以将URL提供给用户,他们可以下载该文件.我遗憾的是没有找到办法在Firefox中做到这一点,是否可能?
有没有其他方法可以用来在工作者和主线程之间传输数据?
Sco*_*and 12
Firefox/Opera/Chrome目前都支持一种叫做Transferable Objects的网络工作者,它非常快 - 也非常容易设置.在这里,我们向ww(web worker)发送一个浏览器分配的数组,该数组由ww填充并返回给浏览器端.这是通过引用传递的,而不是副本:浏览器< - > ww
在浏览器方面:
var huge_array = new Float32Array(SIZE);
// worker.postMessage(huge_array.buffer); // old way
worker.postMessage(huge_array.buffer, [huge_array.buffer]); // new Trans Obj
Run Code Online (Sandbox Code Playgroud)
然后在网络工作者内部:
self.onmessage = function(e) {
var flt_arr = new Float32Array(e.data);
// typically you might want to populate flt_arr here
// now send data structure back to browser
// self.postMessage(flt_arr.buffer); // old way
self.postMessage(flt_arr.buffer, [flt_arr.buffer]); // new Trans Obj way
}
Run Code Online (Sandbox Code Playgroud)
通过简单地将数据对象放在方括号[此处]中,这将提示js使用Transferable Object模式.当发送包含多个变量的javascript对象时,这也很有效,而不仅仅是类型化数组.
引用:
可转移对象是未被复制的对象(例如,使用类似结构化克隆的东西).相反,数据从一个上下文传输到另一个上下文.一旦转移到新上下文,调用上下文中的"版本"将不再可用.例如,将ArrayBuffer从主应用程序传输到Worker时,主线程中的原始ArrayBuffer将被清除,不再可用.这极大地提高了向工作人员发送数据的性能
http://html5-demos.appspot.com/static/workers/transferables/index.html https://html.spec.whatwg.org/multipage/workers.html
根据这个WebWorkers 教程,WebWorkers 现在支持传递 File 和 Blob 对象以及基本上任何可以与结构化克隆算法一起使用的对象......或者至少 Chrome 做到了,可能是因为它实现了 FileSystem API。我不知道这是否是主要原因,但我希望不是,事实上这个功能是在其他浏览器中实现的......能够在后台处理用户选择的文件是一件好事。