[英]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.