簡體   English   中英

等待通過RxJ解決的承諾

[英]Wait for a promise to resolve with RxJs

我正在嘗試使用RxJS v5 beta為表單實現“保存類型”功能。

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

我以這個問題為起點: RxJS等到答應解決

但是,使用此帖子中的解決方案,將同時向后端發送請求。

我的目標是僅發送一個請求,然后將后續請求推遲到運行中的請求完成為止。 請求完成后,應發出最后一個未決事件(就像debounceTime的情況一樣)

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

workaround功能使用存儲在“流”外部的promise來阻止並等待先前的請求。 這有效,並且僅發送對最后一個輸入值的請求。 但是,這似乎不符合RxJs的概念,並且感覺很hack。

有沒有辦法用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/rxjs@5.0.0-rc.2/dist/global/Rx.js"></script> 

如果concatMap()順序運行請求而不丟棄任何請求,請使用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,控制台

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

編輯 :在較新的RxJS版本中,您甚至不需要使用fromPromise (或from ),只需在concatMap返回Promise。

您可以根據承諾創建可觀察對象,並使用use delayWhen運算符,以便等到該可觀察對象發出(承諾解決)。

import { timer } from 'rxjs';
import { delayWhen, from } from 'rxjs/operators';

const myPromise = new Promise(resolve => setTimeout(resolve, 3000)); // will resolve in 3 sec


const waitable = timer(0, 1000).pipe(delayWhen(() => from(myPromise)));
waitable.subscribe(x => console.log(x));

每次發射應延遲3秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM