Ecmascript 6 Rxjs:每X秒重复一次Ajax调用,但等待最后一次调用完成
我想在订阅autorefresher Observable时每x秒查询一次API,确保在发送另一个请求之前完成最后一个请求Ecmascript 6 Rxjs:每X秒重复一次Ajax调用,但等待最后一次调用完成,ecmascript-6,rxjs,rxjs5,Ecmascript 6,Rxjs,Rxjs5,我想在订阅autorefresher Observable时每x秒查询一次API,确保在发送另一个请求之前完成最后一个请求 let autoRefresher = new Observable().exhaustMap(() => Observable.defer(() => { return someService.returningAPromise(); }).timeout(refreshIntervalInMs).repeat()); 有更好的方法吗?如何在每次都不
let autoRefresher = new Observable().exhaustMap(() => Observable.defer(() => {
return someService.returningAPromise();
}).timeout(refreshIntervalInMs).repeat());
有更好的方法吗?如何在每次都不创建新的可观察对象的情况下更新刷新间隔?我会这样做:
import {Observable} from 'rxjs';
function doRequest() {
if (Math.random() < 0.25) {
return Observable.of('HTTP Response').delay(3000);
} else {
return Observable.of('HTTP Response');
}
}
let autoRefresher = Observable.timer(0, 1000)
.exhaustMap(doRequest)
.subscribe(response => {
console.log(response);
});
从'rxjs'导入{Observable};
函数doRequest(){
if(Math.random()<0.25){
返回可观察的('HTTP响应')。延迟(3000);
}否则{
可观察的返回值('HTTP响应');
}
}
让autoRefresher=可观察计时器(0,1000)
.废气排放图(doRequest)
.订阅(响应=>{
控制台日志(响应);
});
见现场演示:
这会随机造成3s延迟。操作符timer()
定期发出一个值。然后订阅前面的可观察对象并忽略所有发出的可观察对象,直到当前可观察对象完成。因此,timer()
正在发出值,但这些值被detain()
忽略
顺便说一句,请注意我使用的是TypeScript。我发现这是一个很老的问题,我只是想提出一个更“稳定”的解决方案。这种方法的问题是,可能有一些窗口没有发出请求,因为计时器以固定的1s间隔发送 例如: 间隔1s,请求持续时间<1s:每1秒发出一个请求,但如果请求需要400ms才能完成,则只需要600ms,直到下一个请求开始(不是1秒) 间隔1s,请求持续时间1,5s:请求在开始时开始,在下一个间隔中,请求仍在运行,因此exhaustMap将对其进行过滤,在第三个间隔中,请求将再次运行(在上一个请求后500ms) 在我的示例中,请求将在再次运行之前始终等待1秒
import { delay, flatMap, repeat, takeUntil } from 'rxjs/operators';
import { of,Subject } from 'rxjs';
function doRequest() {
if (Math.random() < 0.25) {
return Observable.of('HTTP Response').delay(3000);
} else {
return Observable.of('HTTP Response');
}
}
const subject: Subject<boolean> = new Subject();
of(null)
.pipe(
// can be used to cancel
takeUntil(subject),
// does request
flatMap(doRequest),
// delays by 1second
delay(1000),
// repeat steps above
repeat(),
)
.subscribe(response => {
console.log(respons);
});
从'rxjs/operators'导入{delay,flatMap,repeat,takeUntil};
从“rxjs”导入{of,Subject};
函数doRequest(){
if(Math.random()<0.25){
返回可观察的('HTTP响应')。延迟(3000);
}否则{
可观察的返回值('HTTP响应');
}
}
常量主题:主题=新主题();
of(空)
.烟斗(
//可以用来取消
takeUntil(主题),
//要求
平面地图(doRequest),
//延迟1秒
延迟(1000),
//重复上述步骤
重复(),
)
.订阅(响应=>{
控制台日志(响应);
});
不错,比我想象的要简单。出于兴趣,Math.random()的作用是什么?@sqwk,它仅用于模拟重叠的请求。但是,这会延迟第一个请求,并且任何后续项在发送到订阅服务器时都已过时。因此,例如,如果您希望间隔为60秒,则请求将完成,延迟60秒,此时数据可能已过时。第一个请求实际上不是延迟,检查文档:或堆栈闪电。我不知道你是什么意思,后面的东西都过时了?