I'm trying to create a worker that uploads file attached with event handler that will update progress bar in my html page. the upload is already working fine in the worker.
I know that web worker has no access to DOM objects, which is where all my progress bars are. so, I'm wondering if there's any work around? I want to do the uploads in worker, but I also want the progress tracking. I'll be uploading several file in parallel, so, each worker (upload) will have its own progress bar. is this doable? or should I let go of web worker altogether and choose different design?
this is what's inside my worker
onmessage = e => {
var xhr = new XMLHttpRequest();
xhr.addEventListener('progress', function(e) {
var done = e.position || e.loaded, total = e.totalSize || e.total;
console.log('xhr progress: ' + (Math.floor(done/total*1000)/10) + '%');
}, false);
if ( xhr.upload ) {
xhr.upload.onprogress = function(e) {
var done = e.position || e.loaded, total = e.totalSize || e.total;
console.log('xhr.upload progress: ' + done + ' / ' + total + ' = ' + (Math.floor(done/total*1000)/10) + '%');
};
}
xhr.onreadystatechange = function(e) {
if ( 4 == this.readyState ) {
console.log(['xhr upload complete', e]);
}
};
xhr.open('post', url, true);
xhr.setRequestHeader("Content-Type","multipart/form-data");
let formData = new FormData();
formData.append("thefile", e.data.payload);
xhr.send(formData)
}
I already prepared some event handler, but currently, it's just logging.
Thanks
The onmessage
events includes a .source
property. This is how you send data back to the client. Inside your progress event listener you would add something like:
e.source.postMessage({uploadName: <unique name>, progress: done});
Watch out, though. You use e
as both the onmessage handler data and the progress event handler. I would recommend making the names of the two unique.
Then in your page you listen for the message:
window.addEventListener('message', (data) => {
// ... read data.progress and send it to the right place on the page
}