-
-
Save reverofevil/d12c894277b314fee900 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
var slice = Array.prototype.slice; | |
function thunkify(fn) { | |
return function (/* args */) { | |
var args = slice.call(arguments); | |
return function (cb) { | |
var args1 = args; | |
args1.push(cb); | |
fn.apply(this, args1); | |
}; | |
}; | |
} | |
// Run the generator | |
// genCons: generator's contructor | |
function run(genCons) { | |
// Make a new generator from that constructor | |
var generator = genCons(); | |
// NB! Variables are stored here to save some stack space. | |
// next() is getting called recursively, and that could lead to | |
// some not so beautiful | |
// A pair of a function that accepts a callback and "done" flag | |
var promise; | |
// Whether callback is called synchronously (immediately) or not | |
var sync; | |
// The value that should be passed from callback to the outer code | |
var value; | |
// `undefined` can actually be defined in an outer scope | |
var undefined; | |
(function next() { | |
// Until the generator is out of states, get the next yield'ed promise | |
while (!(promise = generator.next(value)).done) { | |
// We're unsure if the callback is called synchronously or not | |
sync = undefined; | |
// Call that promise | |
promise.value(function (/* args */) { | |
// Get the arguments with which the callback was called | |
value = slice.call(arguments); | |
// Was this callback called asynchronously? | |
if (sync === undefined) { | |
// No, it wasn't. Let the `if` down there know this fact | |
sync = true; | |
} else { | |
// Yes, it was. `if` operator down here have set `sync == false`. | |
// Proceed into running that generator | |
next(); | |
} | |
}); | |
// That callback wasn't called synchronously by the promise | |
if (sync === undefined) { | |
sync = false; | |
break; | |
} | |
} | |
})(); | |
} | |
function test(a, b, cb) { | |
setTimeout(function () { | |
cb(a + b); | |
}, 100); | |
} | |
var g = thunkify(test); | |
run(function* () { | |
console.log(yield g(1, 2)); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment