Observables:Chaining promises&在每个承诺上发射事件

时间:2018-04-11 15:16:16

标签: javascript promise rxjs observable

我刚刚阅读了这个问题RxJS Promise Composition (passing data)并提出了一个问题。

设置与上述问题相同:我有3个承诺。

 const p1 = () => Promise.resolve(1);
 const p2 = x => { const val = x + 1; return Promise.resolve(val); };
 const p3 = x => {
      const isEven = x => x % 2 === 0;
      return Promise.resolve(isEven(x));
 };

我按照答案链接他们,就像这样:

 var chainedPromises$ = 
     Rx.Observable.just()
             .flatMap(p1)
             .flatMap(p2)
             .flatMap(p3);

但是,chainedPromises$仅在所有承诺链的末尾激活一次,并且解析后的值为true。即:

chainedPromises$.subscribe(function(x){console.log(x)}); // Logs `true`

如何更改chainedPromises$以便在每个承诺结束时触发一次?即:

chainedPromises$.subscribe(function(x){console.log(x)});
// Logs `1`
// Logs `2`
// Logs `true`

3 个答案:

答案 0 :(得分:2)

看起来你需要发出生成的值并且在链的下一步中使用它。我不知道是否有糖,但是我明白了这一点。

Observable
  .fromPromise(p1())
  .flatMap(val => Observable.merge(
    Observable.fromPromise(p2(val))
      .flatMap(val => Observable.merge(
        Observable.fromPromise(p3(val)),
        Observable.of(val)
      )),
    Observable.of(val)
  ))
  .subscribe(console.log);

您可以看到it正常工作。

答案 1 :(得分:1)

不要使用mergeMap来制作" map"一个值到另一个值并使用仅在前一个Observable完成时订阅Observable的concat。这样,您可以在一次处理一个Observable的同时实现相同的效果,但每次发射都会传播:

Observable.concat(p1, p2, p3)
  .subscribe(console.log);

编辑:

Observable.of(null)
  .expand((value, index) => {
    switch (index) {
      case 0:
        return p1();
      case 1:
        return p2(value);
      case 2:
        return p3(value);
      default:
        return Observable.empty();
    }
  })
  .filter((value, index) => index > 0) // Ignore the `null` value that was necessary to start the chain
  .subscribe(console.log);

打印:

1
2
true

查看实时演示(开放式控制台):https://stackblitz.com/edit/rxjs5-fucqhq?file=index.ts

答案 2 :(得分:1)

对我来说,你在这里浪费了一个可观察的全部观点。

如果您有一组Promise,您希望订阅者以流的形式接收,只需转到next,您现在就可以订阅一个流。

以下是一个例子。 - >



const p1 = () => Promise.resolve(1);
const p2 = x => { const val = x + 1; return  Promise.resolve(val); };
const p3 = x => {
  const isEven = x => x % 2 === 0;
  return Promise.resolve(isEven(x));
};

const chainedProm = (observer) => {
  let params;
  return async (p) => 
    observer.next(params = await p(params));
};

var observable = Rx.Observable.create(async function (observer) {
  const doProm = chainedProm(observer);
  await doProm(p1);
  await doProm(p2);
  await doProm(p3);
  observer.complete();
});


observable.subscribe(function(x){console.log(x)});

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.9/Rx.min.js"></script>
&#13;
&#13;
&#13;