2017-07-11 23 views
2

例如,假設我想進行一些API調用。我正在處理的api很容易出現競爭狀況,所以如果我在同一時間更新服務器上的同一條數據時發出3個api調用,它可能會丟失一些數據。rxjs運算符與concatmap類似,但在發射下一個請求之前等待每個請求?

因此,我想排隊我的請求,然後在發出下一個請求之前開啓等待響應返回。

基本上我需要類似concatMap的東西,但concatMap的問題是它同時觸發所有的請求。我需要concatMap在發射下一個請求之前等待。我正在使用rxjs 5.

這裏是一個使用angular2的插入程序,您可以在其中單擊按鈕。當你點擊1秒按鈕時,一個觀測值將被創建,並在1秒後返回。有2秒和3秒按鈕。

https://plnkr.co/edit/6F4JrVueQX8PjPinZqIk?p=preview

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Wait:</h2> 

     <button (click)="start(1)">1 sec</button> 
     <button (click)="start(2)">2 sec</button> 
     <button (click)="start(3)">3 sec</button> 
    </div> 
    `, 
}) 
export class App { 


    constructor() { 
    } 

    start(wait) { 

    const waitSecs = parseInt(wait) * 1000; 

    of('clicked').delay(waitSecs).subscribe(
     val => console.log(wait) 
    ) 

    // Expected behavior: 
    // I click 3 sec, 2 sec, and 1 sec right after another. Then 
    // the console log should output 3, 2, 1. Right now it's 
    // outputting 1, 2, 3. 

    } 
} 

我點擊3秒,2秒​​,並在之後將另1秒後,我與這個應用程序的理想行爲會。然後控制檯應該輸出3,2,1。現在它是 輸出1,2,3.

回答

3

既然你想擁有唯一的要求執行,你可以使用mergeMap()運營商與concurrency設置爲1.請注意,這意味着待發送的項目將在您的mergeMap ope中排隊rator會導致記憶問題。

Rx.Observable.from([3,5,2,1]) 
 
    .mergeMap(
 
    i => { 
 
     return Rx.Observable.of(i) 
 
     .do(i => console.log(`starting request for ${i}`)) 
 
     .delay(1000) 
 
     .do(null,null,() => console.log(`finished request for ${i}`)); 
 
    }, 
 
    null, 
 
    1 /* concurrency limited to 1 */ 
 
) 
 
    .subscribe(val => console.log(`received value: ${val}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.2/Rx.js"></script>

+0

這個工程,我更新了我的掠奪者,我不再得到這個問題:https://plnkr.co/edit/EtC8czwAzhRaMEmrTG0s?p=preview – seescode

相關問題