For more tips like this, sign up to the weekly newsletter!

Promisify FileReader

FileReader requires event listeners to handle the result and the potential errors. Its reliance on callbacks makes it hard to insert it into a Promise-based asynchronous flow.

But it can be easily wrapped in a Promise, making it await-able:

const read = (blob) => new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.onload = (event) => resolve(event.target.result);
  reader.onerror = reject;
  reader.readAsDataURL(blob);
});

This snippet returns a Promise by creating a new FileReader instance, attaching the listeners, and finally starting the conversion.

To use it, either as a Promise:

read(blob).then((result) => ...);

Or with async/await:

const result = await read(blob);
Cleaning up the listeners

At the time of the writing, if you Googled "promisify filereader", the first result was this gist. As you can see, it goes great lengths to clean up all the handlers attached to the FileReader after the Promise settles.

But as it turns out, there is no need for such cleanup.

If you profile the simpler implementation, you can see that there are no memory leaks.

Try it
References
Learn more: