Ecmascript 6 Rxjs:每X秒重复一次Ajax调用,但等待最后一次调用完成

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()); 有更好的方法吗?如何在每次都不

我想在订阅autorefresher Observable时每x秒查询一次API,确保在发送另一个请求之前完成最后一个请求

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秒,此时数据可能已过时。第一个请求实际上不是延迟,检查文档:或堆栈闪电。我不知道你是什么意思,后面的东西都过时了?