У меня есть поток, который испускает некоторые данные.
const data$ = Rx
.Observable
.interval(500)
.map(() => Math.random() * 100)
И я хотел бы вычислить среднее значение для всех полученных значений в течение определенного периода времени (например, каждую секунду)
Если поток data$
испускает -2-2-2-4|
, Я бы хотел, чтобы результирующий поток был ---2---3|
Как бы вы это сделали с помощью rxjs
(версия 5)
bufferTime
- это путь:
Rx.Observable
.interval(500)
.map(() => Math.random() * 100)
.do(console.log)
.bufferTime(2000)
.map(items => {
return items.reduce((acc, cur) => acc + cur, 0) / items.length;
})
.take(3)
.subscribe(val => {
console.log('mean: ' + val);
})
<script src="https://npmcdn.com/@reactivex/[email protected]/dist/global/Rx.js"></script>
Хорошо, точка Maxime действительна. Если вам нужно вычислить среднее значение большого числа значений, используйте windowTime
:
var interval = Rx.Observable.interval(2000);
Rx.Observable
.interval(500)
.map(() => Math.random() * 100)
.do(console.log)
.window(interval)
.map(win => {
return win.reduce((acc, cur) => {
acc.count++;
acc.sum += cur;
return acc;
}, {
count: 0,
sum: 0,
});
})
.mergeAll()
.filter(val => val.count != 0)
.map(val => val.sum / val.count)
.take(3)
.subscribe(val => {
console.log('mean: ' + val);
})
<script src="https://npmcdn.com/@reactivex/[email protected]/dist/global/Rx.js"></script>
Ответ Сергея Соколова может быть о'кей, если вам действительно нужно каждую секунду поймать ценность. Но пусть скажем, например, что это скорее будет каждый час, bufferTime
потенциально должен сохранить в памяти значения за это время. И здесь, если я понимаю вашу проблему, вам не нужно сохранять эти значения.
Поэтому может быть лучше сделать что-то подобное:
const { Observable } = Rx;
const tick$ = Observable.interval(2000);
const myObs$ = Observable
.interval(500)
.map(() => Math.random() * 100)
.do(x => console.log('Emit ${x}'));
const finalObs$ = tick$
.withLatestFrom(myObs$)
.map(([_, val]) => val)
.do(x => console.warn('Taken ${x}'));
// only to test
finalObs$.take(3).subscribe();
Выход:
И каждый console.log
здесь просто для отладки, но в вашем окончательном наблюдаемом вы будете иметь только желтое значение из вышеприведенного захвата экрана.
Здесь рабочий Plunkr https://plnkr.co/edit/sR4Dg1gD3Zh2yWUtl0RI?p=preview