2017-04-10 53 views
3

比方說,我有一個流(觀察到的),還有一些元素:如何等待一個承諾,以解決和跳過RxJS中間元素呢?

--a---b-c---d-- 

如果我有一個函數,這些元素之一,並返回一個承諾,就像一個請求,我做的是一個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)產生的副作用。

回答

3

你可以嘗試,如果你使用rxjs V4使用flatMapFirst。我無法確定運營商是否存在於rxjs v5中。從文檔:

的flatMapFirst操作類似於上文描述的flatMap和concatMap 方法,但是,而不是通過從 轉化項發射所有由所有觀測量使操作者產生的發射的 項源觀察的,而不是flatMapFirst傳播 第一個可觀測專門直到它完成它開始訂閱到下一個可觀測 之前。當前可觀察完成之前來 觀測會被丟棄,不會 傳播。

代碼可能是這樣的:

source$.flatMapFirst(makeRequest) 

什麼會發生在這裏的是,進入b將導致創作的makeRequest(b),與同爲c。然而,makeRequest(c)永遠不會被訂閱,這意味着其影響可能包括其執行不會被執行。

如果makeRequest本身(即的功能,而不是觀察到的makeRequest(x)實際上是做一些特效來創建其觀察到的輸出,並且要防止這種情況,那麼你可以使用defer

source$.flatMapFirst(x => Rx.Observable.defer(() => makeRequest(x))) 

您還可以查看以前的答案如下對於更多的例子使用defer

+3

沒錯,如果你使用的是RxJS 5,'flatMapFirst'已經[重命名](https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md#operators-renamed-or-removed)到['exhaustMap' ](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-exhaustMap)。 – cartant

+0

對不起,雖然這是非常有用的,但我忘了提及我想避免函數被完全調用。那可能嗎?我會更新這個問題來包含這個問題。 –

+0

避免函數被完全調用是什麼意思?您需要發佈一些代碼,但原則上,因爲您的observable未訂閱,所以不會執行任何操作。雖然在某些情況下可以執行請求,但只有響應放在可觀察對象中,在這種情況下,您可以在訂閱時使用'defer'來推遲請求的執行。如果您發佈了一些代碼,我可以更清楚地解釋這個 – user3743222