Ответ 1
Наблюдаемые изменения push, и, следовательно, контролируемая, а не функция, реагирующая на нее, находится под контролем. Генераторы, с другой стороны, требуют вытащить из них значения. Таким образом, функция, которая будет реагировать на новое значение, определяет, когда она готова к новому значению.
У меня были проблемы с противодавлением с помощью наблюдаемых, но с генераторами вы можете позволять значениям так медленно, как вы хотите.
Изменить: последний вопрос. Promises являются только наблюдаемыми, которые только излучают один раз, поэтому я не думаю, что они будут соревноваться друг с другом. Я думаю, что настоящая битва будет асинхронной/ожидающей против наблюдаемых, а async/await имеет начало и уже находится в С# (а теперь Node.js). Но наблюдаемые имеют ощущение сладкой FRP, и функциональная программирование супер крута, поэтому я думаю, что они оба получат хороший кусок mindshare.
Edit2: André Staltz, автор Cycle.js и xstream, и автор Rx.js, написал замечательную статью о том, как связаны генераторы и наблюдатели (в 2018-01-31). В частности, он показывает, как они оба наследуются от общего базового класса.
И теперь потребитель может быть Слушателем ( "наблюдателем" ) или Пуллером, его до потребителя, будет ли он вытаскивать производителя или нет. И производитель может быть Listenable ( "наблюдаемый" ) или "Pullable" ( "iterable" ), вплоть до производителя, если он отправляет данные проактивно или только по требованию. Как вы можете видеть, и потребитель, и производитель - простые функции одного типа:
(num, полезная нагрузка) = > void
Таким образом, любой оператор, который мы построим, будет работать как для реактивного программирования, так и для итерируемого программирования, просто потому, что линия между этими двумя режимами становится размытой, а ее не больше об наблюдаемых по сравнению с итерабельными, а именно о преобразованиях данных между производителем и потребителем.
Я рекомендую прочитать его [ссылка]. В статье представлена " Callbags", спецификация для обратных вызовов, используемых для реактивного и итеративного программирования. Он реализует эту спецификацию, чтобы сделать крошечную библиотеку для итеративного и реактивного программирования. Чтобы побудить вас прочитать статью и проверить библиотеку, вот несколько примеров из библиотеки 7kb на основе спецификации, которую он представляет:
Пример реактивного программирования
Выберите первые 5 нечетных чисел из часов, которые тикают каждую секунду, затем начните их наблюдать:
const {forEach, interval, map, filter, take, pipe} = require('callbag-basics');
pipe(
interval(1000),
map(x => x + 1),
filter(x => x % 2),
take(5),
forEach(x => console.log(x))
);
// 1
// 3
// 5
// 7
// 9
Итерируемый пример программирования
Из диапазона чисел выберите 5 из них и разделите их на 4, затем начните вытягивать их по одному:
const {forEach, fromIter, take, map, pipe} = require('callbag-basics');
function* range(from, to) {
let i = from;
while (i <= to) {
yield i;
i++;
}
}
pipe(
fromIter(range(40, 99)), // 40, 41, 42, 43, 44, 45, 46, ...
take(5), // 40, 41, 42, 43, 44
map(x => x / 4), // 10, 10.25, 10.5, 10.75, 11
forEach(x => console.log(x))
);
// 10
// 10.25
// 10.5
// 10.75
// 11