将blob内容读入现有的SharedArrayBuffer

时间:2017-06-26 20:45:02

标签: javascript

我试图找到一种最有效的方法来将Blob的内容读入现有的SharedArrayBuffer,这是一个等待缓冲区被弹出的工作者。在我的例子中,我可以保证SharedArrayBuffer至少足以保存Blob的全部内容。我提出的最佳方法是:

// Assume 'blob' is the blob we are reading
// and 'buffer' is the SharedArrayBuffer.
const fr = new FileReader();
fr.addEventListener('load', e =>
  new Uint8Array(buffer).set(new Uint8Array(e.target.result)));
fr.readAsArrayBuffer(blob);

这似乎效率低下,特别是如果读取的blob相对较大。

1 个答案:

答案 0 :(得分:1)

>>> from dateparser.date import DateDataParser Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'dateparser' >>> 不是Blob个对象。此外,Transferable上没有.readAsSharedArrayBuffer方法可用。

但是,如果您只需要同时读取来自多个工作人员的FileReader,我相信您可以通过Blobfetch实现此目标,不过我尚未对多名工人进行测试:

URL.createObjectURL()

否则,据我所知,实际上没有一种有效的方法可以将文件中的数据加载到// === main thread === let objectUrl = URL.createObjectURL(blob); worker1.postMessage(objectUrl); worker2.postMessage(objectUrl); // === worker 1 & 2 === self.onmessage = msg => { fetch(msg.data) .then(res => res.blob()) .then(blob => { doSomethingWithBlob(blob); }); };

我还提供了一种方法,用于将blob的块从主线程传输到单个worker。对于我的用例,文件太大,无论如何都不能将整个内容读入单个数组缓冲区(共享或不共享),因此我使用SharedArrayBuffer来处理块。通过使用.slice .postMessage的多个Transferable来电,这样的内容可让您以类似流的方式向单个工作人员提供大量数据:

ArrayBuffer

这会将一大块数据读入主线程中的// === main thread === let eof = false; let nextBuffer = null; let workerReady = true; let read = 0; function nextChunk() { let end = read + chunkSize; if(end >= file.length) { end = file.length; eof = true; } let slice = file.slice(read, end); read = end; fr.readAsArrayBuffer(slice); } fr.onload = event => { let ab = event.target.result; if(workerReady) { worker.postMessage(ab, [ab]); workerReady = false; if(!eof) nextChunk(); } else { nextBuffer = ab; } }; // wait until the worker finished the last chunk // ... otherwise we'll flood main thread's heap worker.onmessage = msg => { if(nextBuffer) { worker.postMessage(nextBuffer, [nextBuffer]); nextBuffer = null; } else if(!eof && msg.ready) { nextChunk(); } }; nextChunk(); // === worker === self.onmessage = msg => { let ab = msg.data; // ... do stuff with data ... self.postMessage({ready:true}); }; ,将其传输给worker,然后在等待worker处理上一个块时将下一个块读入内存。这基本上可以确保两个线程始终保持忙碌状态。