0

I have a JavaScript program, (it's actually a TypeScript program), that reads a file chunk by chunk with a FileReader:

while (j < size) {
    let blob = selectedFiles[i].slice(offset, offset + chunk_size);
    let reader = new FileReader();
    reader.addEventListener('load', async function () {
        let wordArray = typeof reader.result === "string" ? CryptoES.lib.WordArray.create(new TextEncoder().encode(reader.result)) : CryptoES.lib.WordArray.create(reader.result);
        let segment = CryptoES.AES.encrypt(wordArray, pass).toString();
        segments.push(segment);
    });
    await reader.readAsArrayBuffer(blob);
    offset += chunk_size;
    j += chunk_size;
}

But when I process the segments Array later, it's empty. If I add an alert() after the while loop, wait a little bit after it appears and then press 'OK', my array has all it's contents it's supposed to have. My async/await doesn't seem to work properly. I'm using it inside an async function. What did I wrong?

Thank you!

EDIT: If you have other improvements for this piece of code, let me know in the comments as I'm still not a pro :)

1 Answer 1

1

readAsArrayBuffer does not return a promise (it returns nothing, in fact), so it doesn't make sense to await it (that does nothing).

Instead, you need to create a promise that resolves when the load event fires and wait on that. I put this part into a separate function readBlobToArrayBuffer for readability, and I also added event listeners on error and abort to reject the promise in that case instead of just hanging indefinitely.

const readBlobToArrayBuffer = blob => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener('load', () => resolve(reader.result));
    reader.addEventListener('error', () => reject(new Error('Reading file failed'));
    reader.addEventListener('abort', () => reject(new Error('Reading file aborted'));
    reader.readAsArrayBuffer(blob);
});

while (j < size) {
    const blob = selectedFiles[i].slice(offset, offset + chunk_size);
    const result = await readBlobToArrayBuffer(blob);
    const wordArray = typeof result === "string"
      ? CryptoES.lib.WordArray.create(new TextEncoder().encode(result))
      : CryptoES.lib.WordArray.create(result);
    const segment = CryptoES.AES.encrypt(wordArray, pass).toString();
    segments.push(segment);
    offset += chunk_size;
    j += chunk_size;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.