【问题标题】:Angular + Rxjs operator - show loader if api not completed within 5 sec show toastr and hide loaderAngular + Rxjs 运算符 - 如果 api 未在 5 秒内完成则显示加载器显示 toastr 并隐藏加载器
【发布时间】:2021-01-22 11:40:29
【问题描述】:

实际上,我们正在尝试避免在文件上传过程中阻止用户进行其他操作。

如果在 5 秒内使用 rxjs 在 angular 中未完成 api,我如何显示 toastr 并隐藏加载器。

uploadFile() {
  this.service.uploadFile(data)
    .pipe(
      //i am looking for operator which will wait 5 sec if and then hide the loader and show the toastr
    )
    .subscribe(() => {
      this.toastr.success('file uploaded successfully');
      this.loader.hide();
    })
}

提前致谢

【问题讨论】:

  • 问题目前并不完全清楚。如果未在 5 秒内完成,您是否希望取消正在进行的请求?或者您是否只想隐藏加载程序并在请求超过 5 秒时显示一条消息作为副作用?
  • 谢谢,我只需要隐藏和显示消息@MichaelD

标签: javascript angular rxjs


【解决方案1】:

您可以像这样创建加载服务:

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class LoadingService {
  private isLoading = new Subject<boolean>();
  constructor() {}

  public start(isHideImmediately: boolean = false) {
    this.isLoading.next(true);
    if (isHideImmediately) {
      setTimeout(() => {
        this.complete()
      }, 5000);
    }
  }
  public complete() {
    this.isLoading.next(false);
  }

  getLoadingStatus(): Observable<boolean> {
    return this.isLoading.asObservable();
  }
}

并且每次调用api都可以在5s加载关闭后默认以start loading方式开始加载

你的代码:

uploadFile() {
  this.loadingService.start();
  this.service.uploadFile(data).subscribe(() => {
    this.toastr.success('file uploaded successfully');
    this.loadingService.complete();
  })
}

【讨论】:

  • 我不想在 5 秒后隐藏加载器。
  • 我知道如果 api 响应时间超过 5 秒,你想隐藏你的加载器是吗?那么在这个服务中,如果 5s 加载器下的 api 响应由 complete() 方法关闭,否则在 5s 加载后由 setTimeout 关闭不正确?
  • 对于其他地方,加载器也需要 5 秒才能隐藏对吗?
  • 不,不看我的回答,我们有另一种名为 complete() 的方法,您可以将其放入您的代码的订阅部分,如下所示 ->“this.loadingService.complete()”,因此当您的回复时可能在 1 秒或 200 毫秒内完成,您的加载将被关闭,但如果超过 5 秒,如 7 秒,加载将由 start 方法中的 setTimeout 关闭
  • start() { this.isLoading.next(true); setTimeout(() => { this.complete() }, 5000);这将为其他 api 调用执行,并且在 5 秒后它会自动隐藏。但我期待只有这个特定的 api
【解决方案2】:

你可以在一段时间后使用普通的 JS setTimeout() 做某事。为了不影响正在进行的 API 请求,您可以将其包含在 RxJS tap 运算符中。此外,您可以使用finalize 运算符,而不是在订阅中隐藏加载程序。这样,如果请求抛出错误,加载程序也将被关闭。

uploadFile() {
  this.service.uploadFile(data).pipe(
    tap(_ => {
      setTimeout(() => {
        this.loader.hide();
        this.toastr.info('Uploading file');
      }, 5000);
    }),
    finalize(() => this.loader.hide())
  )
  .subscribe(() => {
    this.toastr.success('file uploaded successfully');
  })
}

但 IMO 对加载程序的硬编码时间限制无助于令人满意的接口。

【讨论】:

    【解决方案3】:

    你可以使用 rxjs 的操作符延迟:

    import { delay } from "rxjs/operators";
        
    uploadFile() {
      this.service.uploadFile(data)
        .pipe(delay(50000))
        .subscribe(() => {
          this.toastr.success('file uploaded successfully');
          this.loader.hide();
         })
    }
        
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2019-02-16
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    相关资源
    最近更新 更多