我刚刚阅读了这个问题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`
答案 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;