Skip to content

micahjon/reliable-filereader

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 

Reliable FileReader

FileReader + Promises + Timeout Period

  • Wraps FileReader onload/onerror events with a Promise for ease of use.
  • Enforces a timeout period in case FileReader does not call onload or onerror within a reasonable timeframe. In some cases, we've found that FileReader just stalls out and never fires an event.
  • Native FileReader will actually call both onload & onerror if an error is thrown downstream in an onload callback, so by using this library you avoid that footgun.

Getting Started

Let me know if you actually use this and I'll start publishing it to npm. In the meantime:

npm i git+https://github.com/micahjon/reliable-filereader.git
import reliableFileReader from 'reliable-filereader';

reliableFileReader('readAsDataURL', blob)
    .then((base64String) => {
        // Do something with base64 string
    })
    .catch((error) => {
        if (/timed out/.test(error)) {
            // FileReader has not responded within 15 seconds
        } else {
            // FileReader fired an error event.
            const errorEvent = error;
        }
    });

Parameters

method - {string}

Name of FileReader method (e.g. "readAsDataURL")

blob - {Blob}

Blob or File to read

options.timeoutMs - {number}

Milliseconds to wait before timing out. Defaults to 15 seconds.

// Only wait 10 seconds before giving up
reliableFileReader('readAsDataURL', blob, { timeoutMs: 10000 });

options.onFinishAfterTimeout - {function}

Passed { error } or { result } when FileReader completes after it times out. Could be useful for determing the ideal timeout period.

const startTime = Date.now();
reliableFileReader('readAsDataURL', blob, {
    onFinishAfterTimeout: ({ result, error }) => {
        const ellapsedSeconds = (Date.now() - startTime) / 1000;
        if (result) {
            reportToAnalytics(`FileReader completed after ${ellapsedSeconds}s`);
        } else {
            reportToAnalytics(`FileReader failed after ${ellapsedSeconds}s`);
        }
    },
});

options.timeoutFunction - {function}

The timeout function to be overriden. By default, it's just a simple wrapper around setTimeout that accepts a callback {function} and timeoutMs {number} and returns a cancellation function, e.g.

function simpleTimeout(callback, timeoutMs) {
    const timeoutId = setTimeout(callback, timeoutMs);
    return stopWaiting;

    function stopWaiting() {
        clearTimeout(timeoutId);
    }
}

If you want to pause the timer while the tab is in the background, you could use this drop-in replacement:

import whileTabVisibleTimeout from 'while-tab-visible-setTimeout';

// Pause timer if user is not viewing this tab, since FileReader will be throttled
// by the browser and will take much longer to complete its task.
reliableFileReader('readAsDataURL', blob, { timeoutFunction: whileTabVisibleTimeout });

See micahjon/while-tab-visible-setTimeout

About

Reliable FileReader wrapper with promises & timeout period.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published