2016-11-14 126 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