I'm using io.js, a fork of node that already supports ES6 generators without the need for special flags, and Kris Kowal's Q library.
What I'm making is a game script, where almost every single action is async, and I'm using Q.spawn
to keep things sane. This is the current state of my code, and it works:
var q = require('q');
var tw = require('./lib/typewriter');
q.spawn(function*() {
tw.clear();
yield tw.type({d:100}, "August 3, 9:47 AM", {w:500});
yield tw.type("District Court");
yield tw.type("Defendant Lobby No. 2", {w:2000});
yield tw.breakLine();
yield tw.type({who:"Phoenix"}, {dh:true}, {d:30}, "(Boy am I nervous!)", {w:1500});
yield tw.breakLine().then(function(){ throw new Error("BOOM!"); });
yield tw.type({who:"Mia"}, {dh:true}, {d:40}, "Wright!", {w:1250});
yield tw.type({di:true}, {d:50}, "Did you", {w:1000}, {d:0}, " ", {d:30}, "turn off the lights?", {w:1000});
yield tw.type({di:true}, {d:400}, ". . .", {w:1000});
yield tw.type({di:true}, {d:40}, "I can't see a thing!", {w:1000});
yield tw.breakLine();
process.exit();
});
However, adding yield to every single line sucks. I'm almost making the jump towards Luvit to escape from this madness, but I'm giving JavaScript its chance.
Under normal circumstances, I can omit most yielding, like this:
var q = require('q');
var tw = require('./lib/typewriter');
q.spawn(function*() {
tw.clear();
tw.type({d:100}, "August 3, 9:47 AM", {w:500});
tw.type("District Court");
tw.type("Defendant Lobby No. 2", {w:2000});
tw.breakLine();
tw.type({who:"Phoenix"}, {dh:true}, {d:30}, "(Boy am I nervous!)", {w:1500});
tw.breakLine();
tw.type({who:"Mia"}, {dh:true}, {d:40}, "Wright!", {w:1250});
tw.type({di:true}, {d:50}, "Did you", {w:1000}, {d:0}, " ", {d:30}, "turn off the lights?", {w:1000});
tw.type({di:true}, {d:400}, ". . .", {w:1000});
tw.type({di:true}, {d:40}, "I can't see a thing!", {w:1000});
yield tw.breakLine();
process.exit();
});
Only one yield is still there, just to be sure process.exit()
won't execute too early. The typewriter module actually queues most commands, so this works. This would be reasonable.
However, if a callback throws somewhere, as in:
tw.breakLine().then(function(){ throw new Error("BOOM!"); });
Then Q will swallow it up and, since there is no catch
handler attached to that promise, it will just be silently garbage collected.
If JavaScript generators just detected expression statements yielding promises and automatically yielded that, it would be awesome (so long as you could opt out of it somehow, of course).
Is there a JavaScript preprocessor that does that?
Or is there some other way to avoid explicitly yielding on every single line but still get exceptions to be caught?