Search code examples
javascriptweb-worker

onmessage in web workers can not access class variable


I am making multithreading file uploading .

when I access to Class variable in myWorker.onmessage, it shows error.

app.4c7f2a2a.js:32 Uncaught TypeError: Cannot read properties of undefined (reading 'length')
    at a.onmessage 

How can I solve this error ?

check my source code.

// queue.js
class Queue {
    constructor() {
        this.items = [];
        this.size = -1;
    }
    sendChunk( chunkId) {
        if (window.Worker) {
            const myWorker = new Worker("/worker.js");
            myWorker.postMessage([chunkId]);
            myWorker.onmessage = function (e) {
                console.log(e.data);
                console.log(this.size); // <-- this make error
            }
        }
    }
}
export default Queue;
// worker.js
onmessage = async function (e) {
    const count = e.data[0];
    const data = {
        count: count,
        local_time: new Date().toLocaleTimeString(),
    };

    fetch('/time', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data),
        })
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            postMessage(JSON.stringify(data));
        })
        .catch((error) => {
            console.error('Error:', error);
        });
}
// main.js
import Queue from './queue';
const q = new Queue();
q.startQueue();

console.log(this.size); makes error.


Solution

  • this will be within the scope of the onmessage function. If you need to use the class variables within the callback of onmessage then, you can store this into some other variable like that in the example below and then access the members within.

    // queue.js
    class Queue {
        constructor() {
            this.items = [];
            this.size = -1;
        }
        sendChunk( chunkId) {
            if (window.Worker) {
                const myWorker = new Worker("/worker.js");
                myWorker.postMessage([chunkId]);
                const that = this
                myWorker.onmessage = function (e) {
                    console.log(e.data);
                    console.log(that.size);
                }
            }
        }
    }
    export default Queue;