[英]Chaining Observables in RxJS
我正在学习 RxJS 和 Angular 2. 假设我有一个带有多个异步 function 调用的 promise 链,这取决于之前的结果,如下所示:
var promiseChain = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
}).then((result) => {
console.log(result);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(result + 2);
}, 1000);
});
}).then((result) => {
console.log(result);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(result + 3);
}, 1000);
});
});
promiseChain.then((finalResult) => {
console.log(finalResult);
});
我尝试仅使用 RxJS 而不使用承诺来做同样的事情,结果如下:
var observableChain = Observable.create((observer) => {
setTimeout(() => {
observer.next(1);
observer.complete();
}, 1000);
}).flatMap((result) => {
console.log(result);
return Observable.create((observer) => {
setTimeout(() => {
observer.next(result + 2);
observer.complete()
}, 1000);
});
}).flatMap((result) => {
console.log(result);
return Observable.create((observer) => {
setTimeout(() => {
observer.next(result + 3);
observer.complete()
}, 1000);
});
});
observableChain.subscribe((finalResult) => {
console.log(finalResult);
});
它产生与 promise 链相同的 output。 我的问题是
我这样做对吗? 我可以对上面的代码进行 RxJS 相关的改进吗
我如何让这个可观察链重复执行? 即在最后添加另一个订阅只会产生额外的 6,尽管我希望它打印 1、3 和 6。
observableChain.subscribe((finalResult) => { console.log(finalResult); });
observableChain.subscribe((finalResult) => { console.log(finalResult); });
1 3 6 6
关于promise composition vs. Rxjs,因为这是一个常见问题,因此您可以参考一些先前关于SO的问题,其中:
基本上, flatMap
相当于Promise.then
。
对于第二个问题,您是要重放已经发出的值,还是要在到达新值时对其进行处理? 在第一种情况下,请检查publishReplay
运算符。 在第二种情况下,标准订阅就足够了。 但是,您可能需要注意感冒。 与热二分法(具体取决于您的来源)(请参见热和冷可观察值:是否存在“热”和“冷”运算符?以对该概念进行图解说明)
澄清示例:
pipe 的顶部可以发出 n 个值(这回答了“我如何让这个可观察的链重复执行”),但随后的链接流发出一个值(因此模仿承诺)。
// Emit three values into the top of this pipe
const topOfPipe = of<string>('chaining', 'some', 'observables');
// If any of the chained observables emit more than 1 value
// then don't use this unless you understand what is going to happen.
const firstObservablePipe = of(1);
const secondObservablePipe = of(2);
const thirdObservablePipe = of(3);
const fourthObservablePipe = of(4);
const addToPreviousStream = (previous) => map(current => previous + current);
const first = (one) => firstObservablePipe.pipe(addToPreviousStream(one));
const second = (two) => secondObservablePipe.pipe(addToPreviousStream(two));
const third = (three) => thirdObservablePipe.pipe(addToPreviousStream(three));
const fourth = (four) => fourthObservablePipe.pipe(addToPreviousStream(four));
topOfPipe.pipe(
mergeMap(first),
mergeMap(second),
mergeMap(third),
mergeMap(fourth),
).subscribe(console.log);
// Output: chaining1234 some1234 observables1234
您还可以使用 concatMap 或 switchMap。 它们都有细微的差别。 请参阅 rxjs 文档以了解。
mergeMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/mergemap
concatMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/concatmap
switchMap: https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.