javascript - Numărați evenimentele pe o perioadă de timp și returnați suma o dată pe secundă în RxJS
Este posibil să numeri evenimentele pe o perioadă de timp și să obții suma o dată pe secundă în RxJS? Am un flux continuu de evenimente care nu se termină niciodată. La fiecare 1 secundă aș dori să obțin numărul total de evenimente din ultimele 5 minute. Ideea este să folosesc acest lucru pentru a popula un grafic în timp real.
Știu cum să fac asta în mod tradițional, dar mi-ar plăcea foarte mult să înțeleg cum se face folosind programarea reactivă.
Răspuns #1
Iată cum aș aborda-o.
Creează un observable care doar numără numărul de evenimente primite și emite acest lucru ca un total în curs (prin scan). Creează un al doilea observable care este doar totalul în curs, întârziat cu 5 minute. Creează un al treilea observable care doar scade observable-ul întârziat din primul observable. Acest lucru va produce totalul în curs al evenimentelor care sunt mai tinere de 5 minute. Creează un observable final care eșantionează acest al treilea observable o dată pe secundă.
const totalLast5Minutes = eventSource.publish(events => {
const runningTotal = events
.scan((e, total) => total + 1, 0)
.startWith(0);
const totalDelayed5Minutes = runningTotal
.delay(5000 * 60)
.startWith(0);
return Rx.Observable
.combineLatest(total, totalDelayed5Minutes, (t, td) => t - td);
});
// only sample the value once per second
Rx.Observable
.interval(1000)
.withLatestFrom(totalLast5Minutes, (interval, total) => total)
.subscribe(total => console.log(`total=${total}`));
Răspunsul #2
Iată o altă metodă de a face asta, care cred că ar putea fi puțin mai simplă. Poți folosi windowWithTime - vezi documentația ReactiveX și RxJS. Poți crea ferestre care se suprapun, astfel încât să ai o fereastră de 5 minute de evenimente, urmată de o altă fereastră de 5 minute de evenimente care a început cu un secundă mai târziu, și încă una după încă o secundă, etc.
Dacă iei numărul fiecăreia dintre aceste ferestre, vei obține o serie de numărători de evenimente de 5 minute, la un interval de un secundă. Ar arăta cam așa:
source.windowWithTime(5 * 60000, 1000) // create 5 minute windows, one second apart
.flatMap(window => window.count()) // take each window and get the count once it completes (after 5 minutes)
.subscribe(count => console.log(count));
Am folosit asta pentru a face exact ceea ce spui - să obțin o rată a evenimentelor pe o fereastră de timp într-un flux continuu de evenimente. Prin suprapunerea ferestrelor, generezi o medie mobilă a activității din flux.
