Search code examples
javascriptcallbackglobal-variablesfileapi

Best way to make file buffer accessible outside a callback function in Javascript for large files?


I am new to JS, and I need to load a file1, decompress a part of it to file2, and then make that decompressed file2 available to user's download--all completely browser-side (no Node.js etc.).

For decompression I have:

let fb;

const decB = document.querySelector('button[id="dec"]')
const inputB = document.querySelector('input[type="file"]')
    
input.addEventListener('change', function(e) {
    

    const r = new FileReader()
    r.onload = function () {
        const archive = new Uint8Array(r.result, start, length)
        try {
            fb = pako.inflate(archive);
         
          } catch (err) {
            console.log(err);
          }
    }
    r.readAsArrayBuffer(input.files[0])
}, false)

decB.addEventListener("click", function(e) {
  try {
    const t = new TextDecoder().decode(fb)
    console.log(t)
    
  } catch(err) {
    console.log(err)
  }
}, false)

I want to be able to access the contents of the result in other functions. Is using a global variable the best way to do it, or is there a more proper solution?


Solution

  • I guess if you want to avoid callbacks and not having a giant code block, then you can try to use async/await instead along with the new promise based reading methods on the blob itself (https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer)

    input.addEventListener('change', async evt => {
      const [file] = input.files
      if (file) {
        const arrayBuffer = await file.slice(28, 7412).arrayBuffer()
        const compressed = new Uint8Array(arrayBuffer)
        fileBuffer = pako.inflate(compressed)
        document.getElementById('Decompress').disabled = false
      } else {
        // input was cleared
      }
    })