我试图找到一种最有效的方法来将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相对较大。
答案 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
,我相信您可以通过Blob
和fetch
实现此目标,不过我尚未对多名工人进行测试:
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处理上一个块时将下一个块读入内存。这基本上可以确保两个线程始终保持忙碌状态。