Rxjs - comment extraire des valeurs multiples à l'intérieur d'un tableau et les retransmettre au flux observable de façon synchrone

j'ai créé un Rx.Observable à partir d'un flux d'événements:

Rx.Observable.fromEvent(recognizeStream, 'data')

dans lequel chaque événement de données ressemble à ceci:

{ error: null, alternatives: [result1, result2, result3] }

je veux plumer chaque valeur à l'intérieur du tableau de alternatives et fusionner ceux-ci dans le flux. Quels opérateurs 1519120920 " dois-je regarder?

autant Que je sache, le flatMap et concatMap pourrait faire le travail, mais je n'ai pas l'idée de leur exemple.

quelqu'un peut-il expliquer quel opérateur je devrais utiliser et me fournir un exemple?

4
demandé sur Mark van Straten 2017-02-02 11:57:15

3 réponses

la famille des opérateurs xxxMap() traitent tous avec des Observables d'ordre supérieur. Ce qui signifie qu'ils vous permettent de créer des Observables à l'intérieur du principal Observable et d'aligner les valeurs résultantes dans le flux primaire. Donc vous pouvez lire la signature de type comme Observable<Observable<T>> => Observable<T>

étant donné que chaque émission x est un flux Observable contenant des émissions de 4 valeurs:

input:  --x----------x 
flatMap   a-a-a-a-|  b-b-b-b-|
result: --a-a-a-a----b-b-b-b-|

Typographie xxxMap (myFnc) retour valeurs

les opérateurs xxxMap() travaillent tous avec des résultats de type Observable , Promise ou Array . Selon ce que vous y mettez sera converti en Observable si nécessaire.

Rx.Observable.of('')
  .flatMap(() => [1,2,3,4])
  .subscribe(val => console.log('array value: ' + val));

Rx.Observable.of('')
  .flatMap(() => Promise.resolve(1))
  .subscribe(val => console.log('promise value: ' + val));

Rx.Observable.of('')
  .flatMap(() => Promise.resolve([1,2,3,4]))
  .subscribe(val => console.log('promise array value: ' + val));

Rx.Observable.of('')
  .flatMap(() => Rx.Observable.from([1,2,3,4]))
  .subscribe(val => console.log('Observable value: ' + val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>

Dans votre cas, vous pouvez facilement flatMap les objets et retourner les tableaux:

Rx.Observable.of({ error: null, alternatives: ['result1', 'result2', 'result3'] })
  .flatMap(val => val.alternatives)
  .subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>

différence entre tous opérateurs xxxMap

Ce n'mergeMap faire

flatMap , plus connu sous le nom de mergeMap will merge toutes les émissions lorsqu'elles entrent dans le flux principal.

enter image description here

concatMap

concatMap attendra que toutes les émissions compléter avant concat le flux suivant:

enter image description here

switchMap

mais switchMap sera abandonner la précédente flux lorsqu'une nouvelle émission est disponible et switch d'émettre des valeurs de la nouvelle vague:

enter image description here

11
répondu Mark van Straten 2017-06-28 07:47:07

vous devez pluck alternatives " ensuite , pour itérer sur le tableau utiliser de , comme de crée un nouveau observable, vous avez besoin de l'aplatir, donc utiliser vous avez besoin flatMap pour faire le travail. Donc finalement vous avez alternatives de nouveau dans le flux.

l'essayer:

var data = {
  error: null,
  alternatives: [{
    result: 1
  }, {
    result: 2
  }, {
    result: 3
  }]
}

var input$ = Rx.Observable.of(data);
input$.pluck('alternatives').flatMap(alternatives => Rx.Observable.from(alternatives)).subscribe(alternative => console.log(alternative));
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.7/dist/global/Rx.umd.js"></script>
2
répondu Victor Godoy 2017-02-02 14:51:05

Opérateurs flatMap() et concatMap() sont à la fois un bon choix. Vous pouvez simplement transformer la propriété alternatives en une autre Observable et ensuite émettre les éléments du tableau fusionnés dans le flux.

const Observables = Rx.Observable;

Observable.of({ error: null, alternatives: ['result1', 'result2', 'result3'] })
  .concatMap(val => {
    return Observable.from(val['alternatives']);
  })
  .subscribe(val => console.log(val));

cette gravure console:

result1
result2
result3

voir démo en direct: https://jsbin.com/foqutab/2/edit?js, console

1
répondu martin 2017-02-02 15:28:43