Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions run.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ function run(generator, callback) {
var iterator = generator(resume);
var data = null, yielded = false;

var next = callback ? nextSafe : nextPlain;

if (!callback) callback = function (err) {
// If the generator ended with an error, throw it globally with setTimeout.
// Throwing locally from a callback is not allowed, and swallowing the
// error is a bad idea, so there's no better option.
if (err) setTimeout(function () { throw err; }, 0);
};

next();
check();

function nextSafe(item) {
function next(err, item) {
var n;
try {
n = iterator.next(item);
n = (err ? iterator.throw(err) : iterator.next(item));
if (!n.done) {
if (typeof n.value === "function") n.value(resume());
yielded = true;
Expand All @@ -25,13 +30,6 @@ function run(generator, callback) {
}
return callback(null, n.value);
}

function nextPlain(item) {
var cont = iterator.next(item).value;
// Pass in resume to continuables if one was yielded.
if (typeof cont === "function") cont(resume());
yielded = true;
}

function resume() {
var done = false;
Expand All @@ -49,8 +47,7 @@ function run(generator, callback) {
var item = data[1];
data = null;
yielded = false;
if (err) return iterator.throw(err);
next(item);
next(err, item);
yielded = true;
}
}
Expand Down
30 changes: 27 additions & 3 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function *run_with_callback(gen) {
console.log("Callback");
yield run(function* (gen) {
yield sleep(1000);
return "Hello"
return "Hello";
}, function (err, value) {
console.log("Callback err: " + err);
console.log("Callback value: " + value);
Expand Down Expand Up @@ -102,7 +102,25 @@ function *run_with_callback_early_exception(gen) {
console.log("Callback value: " + value);
gen()(null, value); // Intentionally suppress the error
});
console.log("End");
testRun("run_with_thrown_error", run_with_thrown_error);
}

function *run_with_thrown_error(gen) {
var inCatch = false;
try {
yield sleep(1);
yield fail();
console.error("this should not happen!");
}
catch (err) {
console.log("in catch: " + err);
console.assert(err);
inCatch = true;
}
yield sleep(1);
console.log("yielded after catch");
console.assert(inCatch);
console.log("\nEnd");
}

function sleep(ms) {
Expand All @@ -117,7 +135,13 @@ function evil() {
setTimeout(function () {
callback(null, 2);
}, 100);
}
};
}

function fail() {
return function (callback) {
callback(Error("throwing error into generator"));
};
}

function decrement(n) {
Expand Down