2016-11-14 171 views
3

我試圖執行「保存類型」功能的表格使用RxJS v5 beta等待承諾與RxJs解決

當用戶鍵入文本字段時,應將數據發佈到後端。我正在創建一個Rx.Subject以激發新用戶輸入的新事件(next())並將其與HTTP請求一起發佈。

我用這個問題作爲出發點:RxJS wait until promise resolved

然而,與這個職位的解決方案,到後端同時請求被髮送。

我的目標是隻發送一個請求並推遲下面的請求,直到一個正在運行的請求完成。請求完成後,應發出最後一個未決事件(如debounceTime中的情況)

以下代碼段中的example函數使用鏈接的SO問題中的方法。這會發送所有輸入值的請求。

workaround函數函數使用存儲在「流」之外的promise來阻塞並等待先前的請求。這工作,並只發送一個請求的最後輸入值。但是,這似乎不符合RxJs的概念,並感覺哈克。

有沒有辦法用RxJS來實現這一點?

function fakeRequest(value) { 
 
    console.log('start request:', value) 
 
    return new Promise((resolve) => { 
 
    setTimeout(() => resolve(value), 1000); 
 
}); 
 
} 
 

 
function example() { 
 
    let subject = new Rx.Subject(); 
 
    
 
    subject 
 
    .debounceTime(500) 
 
    .switchMap(input => fakeRequest(input)) 
 
    .subscribe(data => console.log(data)) 
 

 
    subject.next('example value 1'); 
 
    subject.next('example value 2'); 
 
    subject.next('example value 3'); 
 
    subject.next('example value 4'); 
 
} 
 

 

 
function workaround() { 
 
    let subject = new Rx.Subject(); 
 

 
    let p = Promise.resolve(); 
 
    subject 
 
    .debounceTime(500) 
 
    .switchMap(input => p.then(() => input)) 
 
    .do(input => p = fakeRequest(input)) 
 
    .subscribe(data => console.log(data)) 
 

 
    subject.next('workaround value 1'); 
 
    subject.next('workaround value 2'); 
 
    subject.next('workaround value 3'); 
 
    subject.next('workaround value 4'); 
 
} 
 

 
example(); 
 
// workaround();
<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/Rx.js"></script>

回答

3

如果你想運行在訂單請求,而不是放棄其中的任何然後用concat()concatMap()運營商。這些等待直到前一個Observable完成,然後繼續下一個。

function fakeRequest(value) { 
    console.log('start request:', value) 
    return new Promise((resolve) => { 
    setTimeout(() => resolve(value), 1000); 
}); 
} 

let subject = new Subject(); 
subject.concatMap(value => Observable.fromPromise(fakeRequest(value))) 
    .subscribe(value => console.log(value)); 

subject.next('example value 1'); 
subject.next('example value 2'); 
subject.next('example value 3'); 
subject.next('example value 4'); 

這將打印到控制檯:

start request: example value 1 
example value 1 
start request: example value 2 
example value 2 
start request: example value 3 
example value 3 
start request: example value 4 
example value 4 

見現場演示:https://jsbin.com/xaluvi/4/edit?js,console

如果你想忽略值,那麼debouncethrottleaudit都是不錯的選擇。

+0

謝謝,這有幫助。但是我現在面臨的問題是,一旦承諾解決,所有被承諾阻止的事件都會被釋放出來。我實際上只想要最後一個發射(如'debounceTime',請參閱我的編輯) – Stefan

+0

@Stefan那麼你想要什麼?將它們全部排出還是僅僅排出最後一個?這聽起來像你需要'auditTime()'運算符http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-audit – martin

+0

只發射最後一個。我正在擺弄「審計」,但無法完成工作。反饋非常感謝。 – Stefan