Ответ 1
Хорошо, я сделал свое собственное решение, подобное тому, которое было представлено в вопросе.
Добро пожаловать в Земля обетованной
Довольно обычный сценарий. Я хочу иметь некоторую развязанную часть кода, которая запускает событие, когда что-то готово. Это произойдет только один раз для запуска всего приложения.
С другой стороны, есть еще одна часть кода, где я хочу, чтобы что-то еще произошло, когда запускались два или более события. Я имею в виду как все, как зависимости.
Хорошо, больше асинхронных вещей вместе... определенно promises правильно?
Тогда я начал думать. Действительно ли разумно использовать pub/sub для одноразовых событий? Не было бы лучше просто сделать доступное обещание, которое решает, как только это событие будет запущено? Однако это означало бы, что мне нужно соединить этот развязанный код. Одна вещь заключается в совместном использовании EventEmitter, но зависит от какого-то кода, чтобы на самом деле создать обещание... это звучит довольно плохо.
Итак, я думаю о каком-то миксе. Наличие модуля, в котором другие модули могут запрашивать "событие" по его имени и получать подготовленный объект Promise. Другой модуль должен затем инициировать это событие и эффективно выполнять/отклонять это событие таким образом.
var promisedLand = require('./promisedLand');
promisedLand.waitFor('event'); // returns promise
promisedLand.resolve('event', value);
promisedLand.reject('event', error);
Что вы думаете об этом решении? Есть ли еще какое-то решение, подобное уже имеющемуся?
Хорошо, я сделал свое собственное решение, подобное тому, которое было представлено в вопросе.
Добро пожаловать в Земля обетованной
Хороший вопрос. Позвольте мне начать с одной вещи: обещания не являются излучателями событий.
Позвольте мне повторить, что это заблуждение, которое приходит много. Обещания не являются излучателями событий. С прогрессированием они могут быть взломаны в виде искалеченного события, но в конце дня. Обещания не являются излучателями событий.
Кто они такие? Обещания - это "поле" над значением, которое вы можете открыть в какой-то момент, используя метод .then
а затем поместите результат в другое поле. Ни больше ни меньше.
Как вы сказали, обещания - это один раз. Если ваше мероприятие является одноразовым событием, то обещания определенно в порядке. По сути, ваше событие - это случайность, и обещания моделируют его большую часть времени.
Проблема использования обещаний в качестве излучателей событий - состав, события прогрессирования в обещаниях просто не очень хорошо сочинялись. Обещает цепочку и сочинения, а события нет. Вот почему библиотека Q - это демпинг-прогрессия в пользу оценки в v2. Вот почему прогрессия никогда не включалась в ECMAScript 6.
Излучатели событий представляют собой совершенно точную абстракцию сами по себе, используют излучатели событий, когда они являются правильным инструментом для моделирования вашего отношения (pub-sub), используют обещания, когда они являются правильным инструментом для моделирования вашего отношения, используют потоки, верный инструмент для моделирования вашего отношения. Просто не используйте один инструмент для всего, потому что это (из опыта) принесет вам только боль.
Что вы ищете? О, это существует. Это довольно замечательно, хотя в нем также есть свои проблемы.
То, что вы ищете, называется FRP - функциональным реактивным программированием. Есть много библиотек, которые делают это с лучшим (на мой взгляд) BaconJS.
У FRP есть понятие наблюдаемых, о которых вы говорили. Вот пример счетчика с сайта BaconJS:
var up = $('#up').asEventStream('click');
var down = $('#down').asEventStream('click');
var counter =
// map up to 1, down to -1
up.map(1).merge(down.map(-1))
// accumulate sum
.scan(0, function(x,y) { return x + y });
// assign observable value to jQuery property text
counter.assign($('#counter'), 'text');
Очень похоже на обещания в цепочке, но не представляет собой прямое продолжение, а сплошное потоковое вещание и раковину.
FRP - очень распространенная и развитая парадигма в функциональных языках, таких как Haskell, и очень применима в JavaScript. Это еще не очень распространено, и у него есть свои недостатки, но он определенно думает так, как вы имели в виду.
Итак, короткое резюме:
Кроме того, вы можете похлопывать себя по спине, думая о парадигме, не зная об этом самостоятельно. Вы этого заслуживаете, честный.