How to Use FileReaderSync in JavaScript Web Workers
The FileReaderSync API provides a straightforward way to
read File or Blob objects synchronously,
returning the file data directly to the execution context. Because
synchronous file input/output blocks code execution until the operation
completes, this interface is exclusively available inside JavaScript Web
Workers. This article explains how FileReaderSync works,
why it is restricted to background threads, the methods it provides, and
how to implement it with practical code examples.
What is FileReaderSync?
In standard browser environments, the asynchronous
FileReader interface uses event listeners
(onload, onerror) or promises to read files
without freezing the user interface. Conversely,
FileReaderSync reads files sequentially and blocks
execution within the worker until the entire file content is loaded into
memory.
By eliminating callback chains and event listeners,
FileReaderSync simplifies algorithmic flows—especially when
performing sequential binary processing, image manipulation, or parsing
large data files.
Why Is It Restricted to Web Workers?
JavaScript in the browser runs on a single main execution thread responsible for handling user interactions, animations, and rendering. If a synchronous file read were executed on the main thread, the entire webpage would freeze until the file was completely read from disk.
Web Workers operate on a separate background thread. Blocking a Web Worker with a synchronous operation has zero impact on the responsiveness of the main UI thread, making synchronous reading safe within this isolated context.
Available Methods
The FileReaderSync interface provides four primary
methods, each returning the read data directly rather than emitting an
event:
readAsArrayBuffer(blob): Reads the specifiedBloborFileand returns the data as anArrayBuffer. This is ideal for binary data processing and WebAssembly integration.readAsText(blob, [encoding]): Reads the content and returns it as a plain text string. An optional encoding parameter (such as'UTF-8') can be provided.readAsDataURL(blob): Reads the file and returns a base64-encoded Data URL string.readAsBinaryString(blob): Reads the file and returns the raw binary data as a string (note: this method is deprecated in favor ofreadAsArrayBuffer).
Implementation Example
To use FileReaderSync, pass a File or
Blob reference from the main thread to a dedicated Web
Worker via postMessage.
1. Main Thread (main.js)
// Initialize the worker
const worker = new Worker('worker.js');
// Handle the file input change event
document.getElementById('fileInput').addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
// Send the File object to the worker
worker.postMessage(file);
}
});
// Receive the processed data from the worker
worker.onmessage = (event) => {
console.log('File content received from worker:', event.data);
};2. Worker Thread
(worker.js)
self.onmessage = function (event) {
const file = event.data;
// Instantiate FileReaderSync
const reader = new FileReaderSync();
try {
// Synchronously read the file as text
const textContent = reader.readAsText(file);
// Perform any heavy synchronous parsing or processing here
const processedData = textContent.toUpperCase();
// Send the result back to the main thread
self.postMessage(processedData);
} catch (error) {
// Synchronous reads throw standard exceptions on failure
self.postMessage({ error: error.message });
}
};Error Handling
Unlike the asynchronous FileReader, which requires
listening to the error event, FileReaderSync
throws standard JavaScript exceptions when a read operation fails (e.g.,
due to file access restrictions or missing files). Wrap calls to
FileReaderSync methods inside standard
try...catch blocks to catch and handle
DOMException errors properly.