Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular rxjs:定期执行一些操作,其间有特定的延迟_Angular_Rxjs_Reactive Programming - Fatal编程技术网

Angular rxjs:定期执行一些操作,其间有特定的延迟

Angular rxjs:定期执行一些操作,其间有特定的延迟,angular,rxjs,reactive-programming,Angular,Rxjs,Reactive Programming,客户端应用程序向服务器发送请求,这可能需要很长时间才能完成。一旦请求完成或失败,客户端应等待一段时间(即10秒),然后再次发送请求 目前的工作解决方案是: appRequest=新主题(); ngOnInit():void{ this.appRequest.delay(10000).subscribe(()=>this.refresh()); 这个。刷新(); } 刷新(){ this.api.getApplications().subscribe(a=>{ 这是更新应用程序(a); this.

客户端应用程序向服务器发送请求,这可能需要很长时间才能完成。一旦请求完成或失败,客户端应等待一段时间(即10秒),然后再次发送请求

目前的工作解决方案是:

appRequest=新主题();
ngOnInit():void{
this.appRequest.delay(10000).subscribe(()=>this.refresh());
这个。刷新();
}
刷新(){
this.api.getApplications().subscribe(a=>{
这是更新应用程序(a);
this.appRequest.next();
},()=>this.appRequest.next()
);
}
有没有更优雅的解决方案

编辑:

我可以使用定时,但我不想发送新的请求,除非以前的请求已经完成。只有在前一个请求完成后,我才想等待10秒钟,然后再次发送请求。这应该无限期地重复

getApplications()
函数由swagger生成,它在内部使用angular的http客户端库。当前的观察结果是,除非您订阅由
getApplications()
返回的
Observable
,否则它不会向服务器发送请求

您正在寻找新的

从上面的链接:

可以使用
.expand()
递归调用函数

var recursiveObservable=this.api.getApplications().delay(10000);
//递归调用
递归可观测
.展开((res)=>{
//如果你想的话,你可以用你的资源做点什么。
返回递归可观察;
})
.subscribe();
上述解决方案将:

  • 调用this.api.getApplications()
  • 延迟10000毫秒
  • 重复步骤1和2
  • 请注意,与所有递归函数一样,
    .expand()
    将无限期地重复自身,直到您实际为其提供终止条件为止。例如,可以使用take运算符指定要重复的次数:

    recursiveObservable
    .展开((res)=>{
    //如果你想的话,你可以用你的资源做点什么。
    返回递归可观察;
    })
    .取(10)//重复10次后停止
    .subscribe()
    
    或者,终端条件可以仅基于布尔值:

    var shouldContinue=true;
    递归可观测
    .展开((res)=>{
    //您可以根据res结果修改shouldContinue。
    return shouldContinue?recursiveObservable:Observable.empty();
    })//当shouldContinue为false时将终止
    .subscribe()
    
    此解决方案仍然使用
    主题
    (并且不止一次),但它不需要其他函数来知道或调用
    刷新()

    注:

    • 记住使用
      takeUntil
      unsubscribe
      ,。。。阻止它。最好在
      mergeMap
      之前执行
      takeUntil
    • expand
      解决方案非常优雅,如有可能,应予以考虑。但在您的情况下,它不适合,因为请求必须在出错时重复,如果您的请求返回多个值,它将失败。需要对这些情况进行特殊处理,以使其正常工作
    repeatWhen()操作符似乎就是为此而设计的,但rxjs风格中缺少示例和文档

    以下是RxJava的文档(描述也适用于RxJs)

    使用
    使用repeatWhen+delay定期轮询数据:
    source.repeatWhen(completed=>completed.delay(5000))

    你的版本可能是

    stopRequesting=新主题();
    恩戈尼尼特(){
    this.api.getApplications()
    .repeatWhen(已完成=>completed.delay(10000))
    .takeUntil(停止请求)
    .subscribe(a=>this.updateApplications(a))
    } 
    恩贡德斯特罗(){
    this.stopRequesting.next(true);
    }
    
    演示

    //记录到html输出
    log=函数(x){document.write(x+“
    ”);}; const stop=新的接收对象(); Rx.可观测间隔(500) .采取(2) .repeatWhen(已完成=>completed.delay(1000)) .takeUntil(停止) .订阅( x=>log(`Next:${x}`), err=>log(`Error:${err}`), ()=>日志('已完成') ); setTimeout(()=>stop.next(true),10000)

    带有
    重复
    延迟
    的解决方案看起来更容易理解:

    unsubscribe = new Subject();
    
    ngOnInit() {
      this.api.getApplications()
        .pipe(
            delay(10000),
            repeat(),
            takeUntil(this.unsubscribe))
        .subscribe(a => this.updateApplications(a))
    } 
    
    ngOnDestroy() {
      this.unsubscribe.next(true);
    }
    

    这种方法的问题在于它不会等待前一个请求完成。我需要它等待前一个请求完成,然后等待10秒,然后提出新的请求。这看起来令人兴奋,但不幸的是它不起作用。也许我忘了提到
    getApplications()
    函数是由swagger生成的,它使用angular的http客户端库。除非我订阅了由
    getApplications()
    提供的observable,否则它甚至不会向服务器发送请求。@Sasa是的,在.expand运算符之后,您需要像往常一样订阅()observable
    const retry$ = new Subject();
    const autoRetryRequest$ = Observable.of('Kick start')
      .merge(retry$)
      .mergeMap(() => {
        const next$ = new Subject()
    
        this.api.getApplications().delay(10000).subscribe(
          value => next$.next(value),
          () => retry$.next(),
          () => retry$.next()
        );
    
        return next$;
      })
      .subscribe((data) => { this.updateApplications(data); });
    
    unsubscribe = new Subject();
    
    ngOnInit() {
      this.api.getApplications()
        .pipe(
            delay(10000),
            repeat(),
            takeUntil(this.unsubscribe))
        .subscribe(a => this.updateApplications(a))
    } 
    
    ngOnDestroy() {
      this.unsubscribe.next(true);
    }