Last active
June 17, 2019 20:52
-
-
Save zz85/25564f1910f1877c39c25ace5e5159bc to your computer and use it in GitHub Desktop.
Greenlet.js Annotated
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is @zz85's attempt to understand and annotate the greenlet.js lib | |
// from https://github.com/developit/greenlet/blob/master/greenlet.js | |
/** Move an async function into its own thread. | |
* @param {Function} fn The (async) function to run in a Worker. | |
*/ | |
export default function greenlet(fn) { // greenlet takes in a function as argument | |
let w = new Worker( // creates a web worker | |
URL.createObjectURL( // that has a local url | |
new Blob([ // created from a blob that has the following content | |
'onmessage =' + ( // function to be called when the message event occurs from main thread | |
f => // fat arrow function to return another function. f is iife passed function arg `fn` | |
({ data }) // that destructures an object with a field data as it's argument | |
=> Promise.resolve() // that is a promise | |
.then( | |
() => f.apply(f, data[1]) // run it's original function f, with data[1] as arguments | |
).then( | |
d => { postMessage([data[0], null, d]); }, // postMessage with d as 3rd arg if promise is successfull | |
e => { postMessage([data[0], '' + e ]); } // otherwise post error as 2nd argument | |
) | |
) + '(' + fn + ')' // this uses a function to string hack to pass the source code as a string. this is a iife | |
]) | |
) | |
), | |
c = 0, // counter | |
p = {}, // an object tracking promise resolvers and rejectors | |
w.onmessage = // callback from worker | |
({ data: [c,e,d] }) => { // destructures message event's data into 3 components | |
p[c] // promise callback for this message call | |
[e ? 1 : 0] // if error, takes first array entry, otherwise second | |
(e||d); // and passes error otherwise original data | |
delete p[c]; // clean up promise callback | |
}; | |
return (...a) => // returns a function when invoked with arguments a | |
new Promise( (y, n) => { // returns a promise | |
p[++c] = [y, n]; // resolver and rejector are stored in an array with a counter | |
w.postMessage([c, a]); // posts to worker with calling id, and arguments | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@developit in line 13 above,
({ data })
could also be destructured as({ data: [c, a] })
to make it clearer.