Angular 2 foreach在数组被另一个函数更改之前执行

时间:2017-07-05 09:24:57

标签: javascript angular typescript asynchronous

我遇到了一些阵列的麻烦,我必须在foreach中改变并再次使用。以下是代码的一部分:

this.selectedDepartementen.forEach(element => {
      this.DepID = element.ID;
      if (this.USERSDepIDs.indexOf(this.DepID) == -1) {
        this.insertDepartementCoupling(this.DepID, this.USERid, this.AJID, res => {
          if (res) {
            this.loading = false;
            return;
          }
          this.removeAllFromArray(this.USERSDepIDs, this.DepID, res => {
            this.USERSDepIDs = res;
          })
        })
      } else
      {
        this.updateDepartementCoupling(this.DepID, this.USERid, this.AJID, res => {
          if (res) {
            this.loading = false;
            return;
          }
          this.removeAllFromArray(this.USERSDepIDs, this.DepID, res => {
            this.USERSDepIDs = res;
          })
        })
      }
    });

正如您所看到的,我正在调用删除上次使用的removeAllFromArray的函数DepID。但是foreach并不等待那个功能,它只是继续前进。我猜这是一个异步的东西,但我该如何解决呢?

提前致谢!

修改

为用户Duncan添加功能insertDepartementCoupling

async insertDepartementCoupling(DepID, USERid, AJID, callback) {
    var test = await this.departementService.insertDepartementCoupling(DepID, USERid, AJID).subscribe(
      data => this.mockdata = data,
      error => {
        this.showMessage("error", "Departement koppeling niet gelukt!", "Departement koppeling niet gelukt, zie console voor meer informatie.");
        callback(true);
      },
      () => {
        if (this.mockdata._body) {
          this.showMessage("error", "Departement koppeling niet gelukt!", "Contacteer de administrator!");
          callback(true);
        } else {
          this.showMessage("succes", "Departement koppeling geslaagd!", "Gebruiker is gekoppeld aan de departement(en).");
          callback(false);
        }
      });
  }

1 个答案:

答案 0 :(得分:1)

如果您更改insertDepartmentCouplingupdateDepartementCoupling,那么它们将返回一个promise,该promise将使用已传递给回调的结果进行解析,并且您也会为{{{{}}执行相同操作。 1}}(那个是否需要异步?),然后创建包含您发布的代码removeAllFromArray的函数,然后您可以使用类似这样的代码:

async

请注意,使用typescript,您可以使用for (const element of this.selectedDepartementen) { this.DepID = element.ID; if (this.USERSDepIDs.indexOf(this.DepID) == -1) { if (await this.insertDepartementCoupling(this.DepID, this.USERid, this.AJID)) { this.loading = false; } else { this.USERSDepIDs = await this.removeAllFromArray(this.USERSDepIDs, this.DepID); } } else { if (await this.updateDepartementCoupling(this.DepID, this.USERid, this.AJID)) { this.loading = false; } else { this.USERSDepIDs = await this.removeAllFromArray(this.USERSDepIDs, this.DepID); } } } 来迭代数组而不是for..of,并避免再次回调。

这段代码现在已经清楚了它的执行方式,特别是forEach循环会一次迭代一次,等待一切都完成,但它仍然是完全异步的。包含它的函数必须使用for关键字声明,并且必须返回async Promise,您可以await或通过.then()回调处理。

你的insertDepartementCoupling函数已经是异步的,并且在内部使用了一个观察者,所以删除回调并返回一个promise的最简单方法就是在observable上使用toPromise()。该承诺将使用最后一个数据值完成,但您可以使用.then()来获取要返回的布尔值:

async insertDepartementCoupling(DepID, USERid, AJID): Promise<boolean> {
    let result = false;
    var test = await this.departementService.insertDepartementCoupling(DepID, USERid, AJID).subscribe(
      data => this.mockdata = data,
      error => {
        this.showMessage("error", "Departement koppeling niet gelukt!", "Departement koppeling niet gelukt, zie console voor meer informatie.");
        result = true;
      },
      () => {
        if (this.mockdata._body) {
          this.showMessage("error", "Departement koppeling niet gelukt!", "Contacteer de administrator!");
          result = true;
        } else {
          this.showMessage("succes", "Departement koppeling geslaagd!", "Gebruiker is gekoppeld aan de departement(en).");
          result = false;
        }
      }).toPromise();
     return result;
  }

或者您可以更快地将Observable转换为承诺,然后您不需要中间变量:

async insertDepartementCoupling(DepID, USERid, AJID): Promise<boolean> {
    return this.departementService.insertDepartementCoupling(DepID, USERid, AJID).toPromise()
    .then(
      data => {
        this.mockdata = data
        if (this.mockdata._body) {
          this.showMessage("error", "Departement koppeling niet gelukt!", "Contacteer de administrator!");
          return true;
        } else {
          this.showMessage("succes", "Departement koppeling geslaagd!", "Gebruiker is gekoppeld aan de departement(en).");
          return false;
        }
      },
      error => {
        this.showMessage("error", "Departement koppeling niet gelukt!", "Departement koppeling niet gelukt, zie console voor meer informatie.");
        return true;
      });
  }