角度-检查列表中的所有订户是否完成

时间:2019-04-05 06:33:00

标签: angular post foreach angular5 subscriber

我使用间隔将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);
   });
 }

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

2 个答案:

答案 0 :(得分:2)

在这种情况下,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

答案 1 :(得分:1)

我相信您希望在所有请求完成后调用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) }))
);