[英]How to wait for a promise to resolve and skip intermediate elements in RxJS?
假設我有一個帶有一些元素的流(可觀察):
--a---b-c---d--
如果我有一個函數接受其中一個元素並返回一個promise,就像一個請求,我用一個函數做一個flatMap
,結果響應流將是這樣的(大寫字母是響應):
--a---b-c---d--
----A----B---CD
但這意味着對c
的請求將在b
請求結束之前開始。 假設我想避免執行c
的請求並將其作為結果:
--a---b-c---d--
----A----B----D
我該如何處理這個問題?
在下面的代碼中,我有一個在1秒,2秒,4秒和7秒后發出的流。 我有一個request
函數,需要兩秒鍾才能完成。 我希望僅使用1,4和7調用該函數(不是2,因為1的請求尚未完成)。
const Rx = require('rx');
const logNext = x => console.log(new Date(), 'Next:', x);
const logError = x => console.log(new Date(), 'Error:', x);
const logCompleted = () => console.log(new Date(), 'Completed.');
Rx.Observable.fromArray([1, 2, 4, 7])
.flatMap(x => Rx.Observable.of(x).delay(x * 1000))
.flatMapFirst(request)
.subscribe(logNext, logError, logCompleted);
function request(x) {
console.log(`Starting request with ${x}`);
return new Promise(resolve => {
setTimeout(
() => {
console.log(`Finishing request with ${x}`);
resolve(x)
},
2000
);
})
}
flatMapFirst
產生正確的響應流,但我想避免調用request(2)
產生的副作用。
你可以嘗試使用flatMapFirst
如果使用rxjs V4。 我無法確定運算符是否存在於rxjs v5中。 從文檔:
flatMapFirst運算符類似於上面描述的flatMap和concatMap方法,但是,不是通過從源Observable轉換項來發出運算符生成的所有Observable發出的所有項,而是flatMapFirst將第一個Observable傳播到它直到它在開始訂閱下一個Observable之前完成。 在當前Observable完成之前的Observable將被刪除並且不會傳播。
代碼可能是這樣的:
source$.flatMapFirst(makeRequest)
這里會發生的是,傳入的b
將導致創建makeRequest(b)
,而c
則相同。 但是, makeRequest(c)
永遠不會被訂閱,這意味着它可能包含在其實現中的效果不會被執行。
如果makeRequest
本身(即函數,而不是可觀察的makeRequest(x)
實際上正在做一些效果來創建它的可觀察輸出,並且你想要阻止它,那么你可以使用defer
:
source$.flatMapFirst(x => Rx.Observable.defer(() => makeRequest(x)))
您還可以查看以前的以下答案,了解更多defer
使用示例:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.