在类似协程的JavaScript函数中避免“产量”重复

时间:2015-04-21 09:01:48

标签: javascript node.js yield q io.js

我正在使用io.js,一个已经支持ES6生成器而不需要特殊标志的节点分支,以及Kris Kowal的Q库。

我正在制作的是一个游戏脚本,几乎每个动作都是异步的,而我正在使用Q.spawn来保持理智。这是我的代码的当前状态,它可以工作:

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();
});

然而,为每一行增加收益很糟糕。我几乎要向Luvit跳跃,以摆脱这种疯狂,但我给了JavaScript机会。

在正常情况下,我可以省略大部分屈服,如下:

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();
});

只有一个产量仍然存在,只是为了确保process.exit()不会过早执行。打字机模块实际上排队了大多数命令,因此这是有效的。这是合理的。

但是,如果回调抛出某处,如:

tw.breakLine().then(function(){ throw new Error("BOOM!"); });

然后Q会吞下它,因为没有catch处理程序附加到该承诺,它将被静默地收集垃圾。

如果JavaScript生成器刚刚检测到表达语句产生promises并自动产生,那么它将 awesome (只要你能以某种方式选择退出它)。

是否有一个JavaScript预处理器可以做到这一点?

或者是否有其他方法可以避免在每一行上明确屈服但仍然可以获取异常?

1 个答案:

答案 0 :(得分:0)

  

如果JavaScript生成器只是检测到表达语句产生了promises并自动产生了它,那就太棒了。

It would be terrible

  

或者是否有其他方法可以避免在每一行上明确屈服但仍然可以获取异常?

不是真的。但对于您的用例,我建议使用异步辅助函数来减少要使用的yield的数量:

var paragraph = q.async(function*(lines) {
    for (let line of lines)
        yield tw.type(...line);
    yield tw.breakLine();
});
q.spawn(function*() {
    tw.clear();
    yield paragraph([
        [{d:100}, "August 3, 9:47 AM", {w:500}],
        ["District Court"],
        ["Defendant Lobby No. 2", {w:2000}]
    ]);
    yield paragraph([
        [{who:"Phoenix"}, {dh:true}, {d:30}, "(Boy am I nervous!)", {w:1500}]
    ]);
    throw new Error("BOOM!");
    yield paragraph([
        [{who:"Mia"}, {dh:true}, {d:40}, "Wright!", {w:1250}],
        [{di:true}, {d:50}, "Did you", {w:1000}, {d:0}, " ", {d:30}, "turn off the lights?", {w:1000}],
        [{di:true}, {d:400}, ". . .", {w:1000}],
        [{di:true}, {d:40}, "I can't see a thing!", {w:1000}]
    ]);
    process.exit();
});