FileReader异步读取方法是否阻止主线程?

2022-07-21 00:00:00 browser javascript filereader

我知道异步方法应该是非阻塞的。但我通常会看到它们应用于fetch()这样的外部操作。即:在浏览器外部处理的内容。

但是FileReader()API呢?文件处理由浏览器完成,对吗?

const reader = new FileReader();

reader.onload = (event) => {
  console.log(event.target.result);
};

reader.onerror = (event) => {
  console.log(event.target.result);
};


// **ONE** OF THE POSSIBLE METHODS BELOW

reader.readAsText(file);
reader.readAsArrayBuffer(file);
reader.readAsBinaryString(file);
reader.readAsDataURL(file);

问题

如果我读取一个100 Gb的文件,它会在某个时候阻塞我的主线程吗?我的意思是,即使它在运行之前等待调用堆栈为空,这会在处理一些大文件时阻塞我的主线程吗?它在这种情况下如何工作?

无论答案是什么,它是否适用于运行最终由浏览器处理的异步操作的任何方法?


解决方案

是"异步"。

数据硬盘/内存访问等将并行完成,这通常需要较长的时间,因此浏览器不需要阻塞主线程,这是基本的I/O操作。

必须将实际reading and processing of the binary data转换为您要求的任何格式in parallel。

并行运行步骤意味着这些步骤将一个接一个地与标准中的其他逻辑同时运行(例如,与事件循环同时运行)。此标准没有定义实现这一点的确切机制,无论是分时协作多任务、纤程、线程、进程,使用不同的超线程、核心、CPU、机器等。相比之下,要立即运行的操作必须中断当前正在运行的任务,运行自己,然后恢复之前运行的任务。

当然,我们不能确定这是否为真正的并行,因为硬件可能不支持并发,但从规格的角度来看,它是异步的。

现在,读取一个100 GB的文件肯定会抛出一个错误,指出您没有足够的可用内存。如果你确实有足够的内存,那么你的计算机很可能无论如何都会受到如此大的数据块的影响。
同样,当通过.Result属性将生成的数据发送回您的线程时,它将占用内存。处理过大的数据可能会影响页面的性能。

相关文章