Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Use WebWorkers and promises to run sync heavy functions in a worker (process) and get the result in a promise
function asyncThread(fn, ...args) {
if (!window.Worker) throw Promise.reject(
new ReferenceError(`WebWorkers aren't available.`)
);
const fnWorker = `
self.onmessage = function(message) {
(${fn.toString()})
.apply(null, message.data)
.then(result => self.postMessage(result));
}`;
return new Promise((resolve, reject) => {
try {
const blob = new Blob([fnWorker], { type: 'text/javascript' });
const blobUrl = window.URL.createObjectURL(blob);
const worker = new Worker(blobUrl);
window.URL.revokeObjectURL(blobUrl);
worker.onmessage = result => {
resolve(result.data);
worker.terminate();
};
worker.onerror = error => {
reject(error);
worker.terminate();
};
worker.postMessage(args);
} catch (error) {
reject(error);
}
});
}
function thread(fn, ...args) {
if (!window.Worker) throw Promise.reject(
new ReferenceError(`WebWorkers aren't available.`)
);
const fnWorker = `
self.onmessage = function(message) {
self.postMessage(
(${fn.toString()}).apply(null, message.data)
);
}`;
return new Promise((resolve, reject) => {
try {
const blob = new Blob([fnWorker], { type: 'text/javascript' });
const blobUrl = window.URL.createObjectURL(blob);
const worker = new Worker(blobUrl);
window.URL.revokeObjectURL(blobUrl);
worker.onmessage = result => {
resolve(result.data);
worker.terminate();
};
worker.onerror = error => {
reject(error);
worker.terminate();
};
worker.postMessage(args);
} catch (error) {
reject(error);
}
});
}
// example with an async/await function
(async () => {
try {
const res1 = await thread(
str => JSON.parse(str),
'{"key": "value"}'
);
console.log(res1);
} catch (error) {
console.error(error);
}
})();
// example using a sum function and promise syntax
// function sum(n1, n2) {
// return n1 + n2;
// }
// thread(sum, 1, 5)
// .then(result => thread(sum, result, 1))
// .then(result => console.log('result', result))
// .catch(error => console.error('error', error));
@abhishekmatta999
Copy link

abhishekmatta999 commented Aug 10, 2021

I'm getting this error while using your code.
message: "Uncaught ReferenceError: _ref14 is not defined"

@sergiodxa
Copy link
Author

@abhishekmatta999 I think there are libraries for doing this, I don't recommend you to use this code as is, it was more of a proof of concept that this was possible, I never used it in production

@abhishekmatta999
Copy link

Can you name some that can be used. And It would be a great help if there is a usage example present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment