【问题标题】:Angular - Check if all Subscriber in a list are finishedAngular - 检查列表中的所有订阅者是否都已完成
【发布时间】:2019-04-05 06:32:59
【问题描述】:

我使用间隔在 forEach 循环中将可变数量的数据发布到后端。我要做的是:如果post方法的第一次调用没有完成但间隔已经想第二次调用该方法,则应该阻塞调用,直到第一次调用完成。

我尝试在代码中显示这一点

setInterval(() => {
  console.log('pendingServiceDataRequests', this.pendingServiceDataRequests);
  if(/* if pendingServiceDataRequests is empty or all subscriber are finished */){
   this.sendData();
  }
}, 5000);


sendData(){
  serviceList = [/* some data */]
  serviceList.forEach((service, index, array) => {
    const currentSub = this.api.post(url, service).subscribe((res: any) => {
            /* delete successful send data */
    }
    this.pendingDataRequests.push(currentSub);
   });
 }

我将所有订阅者放在一个列表中,但我不知道如何检查所有请求是否都已完成

【问题讨论】:

    标签: angular post foreach angular5 subscriber


    【解决方案1】:

    ConactMap 在这种情况下是正确的。试试这个:

    sendData() {
        serviceList = [/* some data */]
        return from(serviceList).pipe(
            concatMap(id => <Observable<Item>> this.api.post(url, service)
        );
    }
    

    https://blog.angularindepth.com/practical-rxjs-in-the-wild-requests-with-concatmap-vs-mergemap-vs-forkjoin-11e5b2efe293

    【讨论】:

      【解决方案2】:

      我相信您想在所有请求完成后调用 sendData() 并在一段时间内执行此操作。尝试执行以下操作:

      ngOnInit() {
        this.timer = setInterval(() => {
          if (!this.activeObservable) {
            this.sendData().subscribe((data) => {
              console.log(data);
            })
          }
        }, 5000)
      }
      
      sendData() {
        this.activeObservable = true;
        // probably you are calling some service to get a fresh lisyt of data and do post requests over them
        let serviceList = [1,2,3,4,5]; // consider this is your sendData
        // create observables in a loop, don't subscribe them:
        // for you, something like:
        //let allPostData = serviceList.map(service => this.api.post(url, service));
        let dummyPostData = serviceList.map(service => of(service));
        return forkJoin(...dummyPostData).pipe(tap(_ => {this.activeObservable = false;}));
      }
      
      ngOnDestroy() {
        if (this.timer) {
          clearTimeout(this.timer)
        }
      }
      

      我在课堂上有一个标志,它告诉我所有的请求是否都完成了,只有我再次调用 sendData(),看看我是如何设置activeObservable

      https://stackblitz.com/edit/angular-ggwnxv

      要处理单个 API 调用中的错误,请使用以下内容:

      let allPostData = serviceList.map(service => this.api.post(url, service).pipe(
          catchError((e) => { return throwError(e); // handle your error here, can also return of(e) }))
      );
      

      【讨论】:

      • Angular 5 有可能吗?但是如果其中一个请求完成或失败,我仍然需要做一些操作
      • @WeSt 是的,可以使用 angular 5,根据您的 rxjs 版本可能会发生变化。我相信 pipeable 运算符是从 rxjs 5.1 引入的,(这对你来说应该没问题)。在我给定的示例中,来自 rxjs 的导入可能与您看到的不同。
      • @WeSt 检查我的编辑以处理单个 API 调用中的错误
      猜你喜欢
      • 2016-12-29
      • 2016-08-24
      • 1970-01-01
      • 2017-02-10
      • 2011-10-18
      • 2021-04-14
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多