2016-11-14 8 views
3

RxJS v5 betaを使用しているフォームに「タイプで保存」機能を実装しようとしています。RxJsで解決する約束を待つ

データは、ユーザーがテキストフィールドに入力するときにバックエンドに送信する必要があります。新しいユーザー入力のために新しいイベント(next())を起動し、HTTPリクエストで投稿するためにRx.Subjectを作成しています。

私は出発点として、この質問を使用しました:RxJS wait until promise resolved

しかし、このポストからの溶液を用いて、バックエンドへの同時リクエストが送信されます。

私の目標は、1つのリクエストのみを送信し、実行中のリクエストが完了するまで次のリクエストを延期することです。要求の完了後、最後の保留中のイベントを発行する必要があります(debounceTimeの場合のように)

exampleの機能は、リンクされたSO質問からのアプローチを使用します。これは、すべての入力値に対する要求を送信します。

workaround関数functionはブロックし、前の要求を待つ「ストリーム」の外に保存された約束を使用しています。これは動作し、最後の入力値に対する要求のみを送信します。しかし、それは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が完了するまで待ってから次の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

はその後debouncethrottleまたはauditは、すべての良い選択です。

+0

ありがとう、これが助けになりました。しかし、私が今問題にしているのは、約束が守られるとすぐに、約束によってブロックされたすべての出来事が放出されるということです。私は実際には最後のものだけを出したい( 'debounceTime'の場合と同じように、私の編集を参照してください) – Stefan

+0

@Stefanそれで何をしたいですか?それらのすべてを放出するか、または最後のものを放出するか? 'auditTime()'演算子が必要なように思えます。http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-audit – martin

+0

最後のものだけを出力します。私は「監査」を手にしていましたが、それを働かせることはできませんでした。フィードバックは非常に高く評価されます。 – Stefan

関連する問題