Предотвращение повторения "доходности" в функции, подобной сопрограмме JavaScript

Я использую io.js, форк узла, который уже поддерживает генераторы ES6 без специальных флагов, и библиотеку 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();
});

Тем не менее, добавление урожая в каждую строку - отстой. Я почти совершаю прыжок в сторону Лувита, чтобы вырваться из этого безумия, но я даю 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 просто обнаруживали выражения выражений, дающие обещания, и автоматически давали их, это было бы здорово (если конечно вы могли бы как-то отказаться от него).

Есть ли препроцессор JavaScript, который делает это?

Или есть какой-то другой способ избежать явной уступки в каждой отдельной строке, но все же получить исключения, которые будут перехвачены?

1 ответ

Решение

Если бы генераторы JavaScript просто обнаруживали выражения выражений, дающие обещания, и автоматически получали их, это было бы замечательно.

Это было бы ужасно.

Или есть какой-то другой способ избежать явной уступки в каждой отдельной строке, но все же получить исключения, которые будут перехвачены?

На самом деле, нет. Но для вашего случая использования я бы рекомендовал использовать асинхронную вспомогательную функцию, чтобы уменьшить количество yields использовать:

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();
});
Другие вопросы по тегам