首页 > 解决方案 > 使用 Angular observable 定期查询 web api 并订阅

问题描述

我有一个 Launch 方法,它接受一些参数并启动一个引擎。当引擎启动时,它会返回实例名称。使用此实例名称,我想定期查询另一个服务,例如每 2 秒以了解状态是否更改为“成功”或“失败”我在第一个订阅中执行了一个 do while 循环,但它没有按预期工作。

instanceStatus: string = "Initialized";
instanceName:string = "InstanceName";


Launch(sessionId: string, projectName: string, f: string[]) {
    this.service.Launch(sessionId, projectName, this.f)
      .pipe(first())
      .subscribe(
        instanceName => {
          localStorage.setItem('instanceName', instanceName);
          this.instanceName = instanceName;
          setTimeout(() => {
            do {
              this.service.getEngineStatus(this.instanceName)
                .pipe(first())
                .subscribe(
                  status => {
                    this.instanceStatus = status;
                    console.log(status);
                    console.log(this.instanceStatus);
                    this.loadingService.showSpinner({ text: 'Modeling is running...' });
                    if (this.instanceStatus === "Succeeded") {
                      this.messageService.add({ severity: Severity.Success, summary: 'Fault modeling completed', detail: 'Via MessageService' });
                      this.messageService.clear();
                    }
                  }
                );
            } while (this.instanceStatus !== "Succeeded")
          }, 2000);
        }
      );
  }



 getEngineStatus(instanceName:string): Observable<string> {
    this.serviceUrl = URL + `?instance=` + instanceName;
    return this._http.get<string>(this.serviceUrl);
  }

标签: angulartypescriptrxjs

解决方案


你看过interval创建操作符吗?我相信这可能是您需要使用的。我使用此运算符试了一下,代码如下所示:

Launch(sessionId: string, projectName: string, f: string[]) {
  this.service
    .Launch(sessionId, projectName, this.f)
    .pipe(
      first(),
      tap((instanceName) => {
        localStorage.setItem('instanceName', instanceName);
        this.instanceName = instanceName;
      }),
      switchMap(() => interval(2000)),
      takeWhile(() => !['Succeeded', 'Failed'].contains(this.instanceStatus)),
      tap(() => {
        this.loadingService.showSpinner({
          text: 'Modeling is running...',
        });
      }),
      switchMap(() => this.service.getEngineStatus(this.instanceName))
    )
    .subscribe((status) => {
      this.instanceStatus = status;
      this.loadingService.hideSpinner();
      console.log(status);
      console.log(this.instanceStatus);

      if (this.instanceStatus === 'Succeeded') {
        this.messageService.add({
          severity: Severity.Success,
          summary: 'Fault modeling completed',
          detail: 'Via MessageService',
        });
        this.messageService.clear();
      }
    });
}

推荐阅读