Skip to content

Instantly share code, notes, and snippets.

@creationix
Last active November 27, 2017 16:06
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/5761021 to your computer and use it in GitHub Desktop.
Save creationix/5761021 to your computer and use it in GitHub Desktop.
A tiny generator helper for consuming callback code directly
function run(generator) {
var iterator = generator(resume);
var data = null, yielded = false;
iterator.next();
yielded = true;
check();
function check() {
while (data && yielded) {
var err = data[0], item = data[1];
data = null;
yielded = false;
if (err) return iterator.throw(err);
iterator.send(item);
yielded = true;
}
}
function resume() {
data = arguments;
check();
}
}
@creationix
Copy link
Author

Here is an example doing a simple sleep

run(function*(resume) {
  console.log("Hello");
  yield setTimeout(resume, 1000);
  console.log("World");
});

@creationix
Copy link
Author

Another example showing it can withstand sync callbacks without blowing the stack

function decr(x, callback) {
  return callback(null, x - 1);
}

run(function*(resume) {
  var x = 10000;
  while (x) {
    x = yield decr(x, resume);
  }
  console.log("Done");
});

@bevacqua
Copy link

bevacqua commented Mar 8, 2014

I know this is super old but to anyone looking into generators now, iterator.send(item) should now be iterator.next(item).

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