1

私は Angular2 アプリを構築しているので、Observables と Reactive Extensions 全体に慣れてきました。TypeScript と rxjs を使用しています。

これで、いくつかのオブジェクトの配列のオブザーバブル、または必要に応じてストリームを取得できました。人物オブジェクトとしましょう。今、Person-objects の他の 2 つのストリームがあり、これらを結合して、常に最新のストリームを取得したいと考えています。

var people$ = getPeople();                  // Observable<Person[]>
var personAdded$ = eventHub.personAdded;    // Observable<Person>;
var personRemoved$ = eventHub.personRemoved // Observable<Person>;

var allwaysUpToDatePeople$ = people$.doSomeMagic(personAdded$, personRemoved$, ...);

people-stream がたとえば 5 人の配列を発行し、その後 personAdded-stream が person を発行する場合、allPeople-stream は 6 の配列を発行します。 personRemoved-stream が人を発行する場合、allPeople-ストリームは、personRemoved-stream によって発行されたばかりのものを除いて、Person-object の配列を発行する必要があります。

この動作を得るためにrxjsに組み込まれた方法はありますか?

4

2 に答える 2

1

You want to merge all of the streams (Ghostbusters style) and then use the scan operator to figure out the state. The scan operator works like Javascript reduce.

Here's a demo...

const initialPeople = ['Person 1', 'Person 2', 'Person 3', 'Person 4'];

const initialPeople$ = Rx.Observable.from(initialPeople);

const addPeople = ['Person 5', 'Person 6', 'Person 7'];

const addPeople$ = Rx.Observable.from(addPeople)
            .concatMap(x => Rx.Observable.of(x).delay(1000)); // this just makes it async

const removePeople = ['Person 2x', 'Person 4x'];

const removePeople$ = Rx.Observable.from(removePeople)
                                              .delay(5000)
                                                .concatMap(x => Rx.Observable.of(x).delay(1000));

const mergedStream$ = Rx.Observable.merge(initialPeople$, addPeople$, removePeople$)

mergedStream$
  .scan((acc, stream) => {
        if (stream.includes('x') && acc.length > 0) {
            const index = acc.findIndex(person => person === stream.replace('x', ''))
            acc.splice(index, 1);
        } else {
            acc.push(stream);
        }
      return acc;
  }, [])
  .subscribe(x => console.log(x))

// In the end, ["Person 1", "Person 3", "Person 5", "Person 6", "Person 7"]

http://jsbin.com/rozetoy/edit?js,console

You didn't mention your data's structure. My use of "x" as a flag is a little (lot) clunky and problematic. But I think you see how you can modify the scan operator to fit your data.

于 2016-10-14T15:51:34.250 に答える