javascript - Laske tapahtumat ajan kuluessa ja tuota summa kerran sekunnissa RxJS:ssä


Onko mahdollista laskea tapahtumia tietyn ajan kuluessa ja saada summa kerran sekunnissa RxJS:ssä? Minulla on jatkuva, ikuisesti jatkuva tapahtumavirta. Joka sekunti haluaisin saada tapahtumien kokonaismäärän viimeisen 5 minuutin aikajaksolta. Ajatuksena on käyttää tätä reaaliaikaisen kaavion täyttämiseen.

Tiedän, miten tämä tehdään perinteisellä tavalla, mutta haluaisin todella ymmärtää, miten se tehdään reaktiivisen ohjelmoinnin avulla.

Vastaus #1

Tässä on, miten minä tarttuisin siihen.

Luo yksi havaittava, joka vain laskee vastaanotettujen tapahtumien määrän ja lähettää sen juoksevana kokonaisuutena (käyttämällä scan). Luo toinen havaittava, joka on vain juokseva kokonaismäärä viiveellä 5 minuuttia. Luo kolmas havaittava, joka yksinkertaisesti vähentää viivästetyn havaittavan ensimmäisestä havaittavasta. Tämä antaa tapahtumien juoksevan kokonaismäärän, jotka ovat nuorempia kuin 5 minuuttia. Luo lopullinen havaittava, joka ottaa näytteen tästä kolmannesta havaittavasta kerran sekunnissa.

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}`));

Vastaus #2

Tässä on toinen tapa tehdä se, jonka mielestäni saattaa olla hieman yksinkertaisempi. Voit käyttää windowWithTime - katso ReactiveX- ja RxJS-dokumentaatio. Voit luoda ikkunoita, jotka menevät päällekkäin, joten voit saada 5 minuutin tapahtumaikkunan, jota seuraa toinen 5 minuutin tapahtumaikkuna, joka alkoi yhden sekunnin myöhemmin, ja vielä yksi sekunti sen jälkeen, jne.

Jos lasket kunkin näistä ikkunoista, saat sarjan 5 minuutin tapahtumalukuja, sekunnin välein. Se näyttäisi jotakuinkin tältä:

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));

Olen käyttänyt tätä juuri siihen, mitä sanot - saadakseni tapahtumien määrän ajanjakson aikana jatkuvassa tapahtumavirrassa. Kun ikkunat menevät päällekkäin, luot liikkuvan keskiarvon virran toiminnasta.