Почему ваш код не работал:
Э, это сложно ... У вас определенно есть двойная подписка на кнопки, то есть код внутри new Observable
для кнопок будетзапустить дважды (сначала, когда подписка на nValue$
, а затем, когда combineLatest
).Запуск дважды означает, что у него есть два обработчика для каждого btn onClick.
Итак, когда вы нажимаете x или y - вы .next
получаете две цепочки Observable: одну, которая обновляет текст btn, а другую - суммуОбновление значения.
Сначала выполняется цепочка для обновления текста кнопки и обновляется значение btn.
Затем активируется цепочка для обновления текста суммы.И когда он суммирует значения - он читает уже обновленные значения из текста btn.Из-за предыдущей цепочки выполните.
Попробуйте внести изменения в свой код подписок по клику, чтобы выполнить регистрацию.Например,
yClick$.subscribe(e => {
const value = parseInt(e.target.textContent)
console.log('y click', value);
s.next(value + 1);
});
Вы увидите, что он запускается дважды.Сначала он читает значение в t1 и обновляет его.Затем он выполняется во второй раз и теперь читает следующее значение из текста btn.
Это, кажется, имеет место.
Важное примечание: этот подход с наблюдаемыми конструкторами и внутреннимподписки следует в первую очередь использовать для обучения.Это подвержено ошибкам и обычно чрезмерно, поскольку большинство задач решаются с использованием существующих операторов или их объединением.Если вы используете конструктор - скорее всего, вы делаете это неправильно.
Существует множество альтернатив конструктора для создания в Observable:
Итак, вот обновленный пример использования каналов:
const makeButtonTextUpdater = buttonElt => value => buttonElt.textContent = value;
const xElt = document.getElementById('x');
const yElt = document.getElementById('y');
const sumElt = document.getElementById('sum');
const xClick$ = rxjs.fromEvent(xElt, 'click');
const yClick$ = rxjs.fromEvent(yElt, 'click');
const sumClick$ = rxjs.fromEvent(sumElt, 'click');
const xSumm$ = xClick$.pipe(
rxjs.operators.startWith(2),
rxjs.operators.scan((acc)=>(acc + 3))
)
const ySumm$ = yClick$.pipe(
rxjs.operators.startWith(5),
rxjs.operators.scan((acc)=>(acc + 1))
);
xSumm$.subscribe(makeButtonTextUpdater(xElt));
ySumm$.subscribe(makeButtonTextUpdater(yElt));
rxjs
.combineLatest(xSumm$, ySumm$, (x, y)=>x+y)
.subscribe(makeButtonTextUpdater(sumElt));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.js"></script>
<label>x: <button id="x">0</button></label>
<label>y: <button id="y">0</button></label>
<label>sum: <button id="sum">0</button></label>