javascript - 避免类似协程的 JavaScript 函数中的 "yield"重复

标签 javascript node.js yield q io.js

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

我正在制作一个游戏脚本,其中几乎每个 Action 都是异步的,并且我使用 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 机会。

一般情况下,我可以省略大部分yield,像这样:

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

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

但是,如果回调在某处抛出,如下所示:

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

然后 Q 将吞噬它,并且由于没有附加到该 Promise 的 catch 处理程序,它只会被默默地进行垃圾收集。

如果 JavaScript 生成器只是检测到产生 Promise 的表达式语句并自动产生它,那就太棒了(当然,只要您可以以某种方式选择退出它)。

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

或者是否有其他方法可以避免在每一行上显式生成但仍然捕获异常?

最佳答案

If JavaScript generators just detected expression statements yielding promises and automatically yielded that, it would be awesome.

It would be terrible .

Or is there some other way to avoid explicitly yielding on every single line but still get exceptions to be caught?

不是真的。但对于您的用例,我建议使用异步辅助函数来减少要使用的 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();
});

关于javascript - 避免类似协程的 JavaScript 函数中的 "yield"重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29767548/

相关文章:

javascript - 如何提交由动态列和行组成的表单

javascript - node.js 中模块模式的最佳实践

node.js - typescript Cipher.getAuthTag 不存在

node.js - 无法在 docker 机器上安装 npm 模块

asynchronous - flutter 和 bloc 异步yield

javascript - CSS 在某些 'frame' 内显示站点部分

javascript - CreateJS:Firefox 中的帧速率较差/奇怪

javascript - 对从 CSV 表生成的 HTML 表进行排序

c++ - Quantlib 求解器未产生与 BondFunctions::yield 相同的到期 yield

Python:多处理池中的产量