Skip to content

Instantly share code, notes, and snippets.

@drmercer
Last active Nov 14, 2017
Embed
What would you like to do?
A jQuery-promise-making wrapper around a Worker thread
function makeThreadedFn(fn) {
var blob = new Blob([
"var main=" + fn.toString() + ";\n"+
"// Generated message handler:\n"+
"onmessage=function(e) {\n"+
" var id = e.data.id;\n"+
" function msg(x) {\n"+
" x.id = id;\n"+
" postMessage(x);\n"+
" };\n"+
" var tools = {\n"+
" progress: x => msg({progress:x}),\n"+
" reject: x => msg({err:x}),\n"+
" resolve: x => msg({result:x}),\n"+
" };\n"+
" try {\n"+
" var arg = e.data.arg;\n"+
" main(arg, tools);\n"+
" } catch (err) {\n"+
" msg({err:err});\n"+
" }\n"+
"};"], {type: 'application/javascript'}
);
var url = URL.createObjectURL(blob);
var w = new Worker(url);
var defs = {};
w.onmessage = function(e) {
var id = e.data.id;
var def = defs[id];
if (!def) return;
// Handle the actual message
var data = e.data;
if ('err' in data) {
def.reject(data.err);
delete defs[id];
return;
}
if ('progress' in data) {
def.notify(data.progress);
}
if ('result' in data) {
def.resolve(data.result);
delete defs[id];
}
};
var nextId = 1;
var thread = function(arg) {
var def = jQuery.Deferred();
var id = nextId++;
defs[id] = def;
w.postMessage({id:id, arg:arg});
return def.promise();
}
thread.kill = function() {
w.terminate();
for (id in defs) {
if (defs[id]) defs[id].reject();
delete defs[id];
}
};
return thread;
}
// ===========================================
// Example thread:
var fibAsync = makeThreadedFn(function(number, tools) {
var i = 0;
setInterval(() => {
tools.progress(i++);
if (i === 10)
tools.resolve("Yay " + number);
}, number);
});
// Example usage:
console.log("Go!");
fibAsync(1000)
.then(
console.log.bind(console, "Result 1:"),
console.error.bind(console, "Err 1:"),
console.log.bind(console, "Progress 1:")
);
fibAsync(700)
.then(
console.log.bind(console, "Result 2:"),
console.error.bind(console, "Err 2:"),
console.log.bind(console, "Progress 2:")
);
setTimeout(() => {
// Kills the thread before it can finish. Rejects all promises.
// fibAsync.kill();
}, 5500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment