【问题标题】:How to wait for code inside subscribe to finish before going to next iteration in forEach loop in Angular如何在 Angular 的 forEach 循环中进行下一次迭代之前等待订阅中的代码完成
【发布时间】:2021-10-15 15:54:46
【问题描述】:

在下面的代码中,我有一个 for 循环,其中一个 API 被调用。我希望完成第一个 API 调用,并且 subscribe 中的代码首先完全执行,然后 for 循环的下一次迭代将开始,API 调用将再次触发下一次迭代。

但目前 API 以并行模式执行。但我希望 API 以顺序方式执行。

                      parentLevelIdArray.forEach(parentLevelId => {
                        this.locModService.deleteAPI(parentLevelId, levelObj.id)
                        .subscribe((response) => {
                          if (response.status === 200) {
                            this.message = 'Image uploaded successfully';
                            this.getSublevels();
                            this.getAllLinkedLevel();
                          } else {
                            this.message = 'Image not uploaded successfully';
                          }
                        }
                        )
                      });

我检查了其他 stackoverflow 链接,但没有得到我的案例的实际答案。请帮忙。

【问题讨论】:

  • 你不能。 forEach 是同步的。订阅通知是异步的。如果你想在系列中做一些异步的事情,请参阅my answer here 的“系列”部分。订阅与承诺的机制略有不同,但概念是相同的。
  • 寻找forkJoin
  • @T.J.Crowder 谢谢。如果您根据我的情况帮助我编写代码 sn-p,那就太好了。
  • 我已经好几年没做过 Angular 了。我可以向您展示 a 方法,但可能有更好的 Angular 特定方法。您确定要在 series 中而不是在 parallel 中完成这些操作吗?因为@Eliseo 向您指出了以 Angular 方式处理并行案例的东西。

标签: angular typescript observable angular-promise angular-observable


【解决方案1】:

我已经用递归方法解决了这个问题。

调用方法 --

let lastIndex = parentLevelIdArray.length - 1;
this.recursiveDelete(parentLevelIdArray, levelObj, lastIndex);

调用方法--

recursiveDelete(parentLevelIdArray, levelObj, lastIndex) {
      if(lastIndex >= 0) {
        this.locModService.deleteAPI(parentLevelIdArray[lastIndex], levelObj.id)
        .subscribe((response) => {
          //console.log("Inside subscribe()...");
          if (response.status === 200) {
            this.message = 'Image uploaded successfully';
            this.getSublevels();
            this.getAllLinkedLevel();
            lastIndex = lastIndex - 1;
            this.recursiveDelete(parentLevelIdArray, levelObj, lastIndex);
          } else {
            this.message = 'Image not uploaded successfully';
          }
        }
        )
      }
  }

【讨论】:

  • 我非常喜欢写更少的代码而不是更多的代码,但我很高兴你能理解。
  • 小心,您永远不会取消订阅来自this.locModService.deleteAPI(..).subscribe(..) 的订阅。如果你想避免任何内存泄漏,你应该这样做
  • @Pilpo 这里没有风险,因为订阅是由 http 调用生成的。那些在发出请求结果后完成。
【解决方案2】:

我这样做的方法是将其转换为可观察的数组,如下所示:

const tasks = parentLevelIdArray.map((parentLevelId) => this.locModService.deleteAPI(parentLevelId, levelObj.id))

这样您就可以根据需要使用concat function 按顺序执行此操作:

concat(tasks).subscribe((response) => {
  if (response.status === 200) {
    this.message = 'Image uploaded successfully';
    this.getSublevels();
    this.getAllLinkedLevel();
  } else {
    this.message = 'Image not uploaded successfully';
  }
}

【讨论】:

  • 谢谢。好的,试试看。
猜你喜欢
  • 2018-05-20
  • 1970-01-01
  • 2014-07-30
  • 2017-12-21
  • 2015-05-12
  • 2022-12-10
  • 2020-11-18
  • 1970-01-01
  • 2016-04-25
相关资源
最近更新 更多