【问题标题】:Calling functions synchronously on ngOnInit在 ngOnInit 上同步调用函数
【发布时间】:2018-05-18 09:37:29
【问题描述】:

我正在开发 Angular 4,我有很多不同的函数立即在 ngOnInit() 上运行。其中大部分是带有回调的 http 请求,它们处理数据并将其传递给下一个函数。

目前我正在使用 setTimeouts,以确保一切都按正确的顺序进行。但是,它并不总是正确的,例如互联网连接速度较慢。 我想确保一切都按正确的顺序进行,没有超时。 为此,我研究了 Promise 和 async await,但我无法将它实现到我的应用程序中,因为 onInit 上调用的函数不仅仅是 http 调用。我不确定我应该将当前回调中的代码放在哪里。

我会给出一个小代码sn-p来说明:

ngOnInit() {

this.getPolygons();

this.customerMasterData();
this.loadMap();

setTimeout(() => this.ngOnInitAfterTimeout(), 2000);}



getPolygons() {
this.dataService.portfolioPolygon()
  .subscribe(
    (response: Response) => {
      const data = response.json();
      const polygon = data.polygons;
      if (polygon) {
        polygon.forEach((item, index) => {
          this.polygons.push(item.polygon);
          this.polygonId.push(item.identificatie);
        });
      }
    },
    (error) => {
      this.isLoading = false;
      console.log(error);
    }
  );}


ngOnInitAfterTimeout() {
    this.winRef.nativeWindow.SetCustomLayers(this.InputArray);

    this.winRef.nativeWindow.SetStartLayers();

    this.loadMapState();

    this.cleanup();

    this.customerMasterData();}


customerMasterData() {

if (this.showAsList) {
  // LIST

  if (this.reverse == false) {
    this.sortDirection = 'A';
  } else {
    this.sortDirection = 'D';
  }

  // string used for filtering the dataset
  let filterString = "";
  if (this.portfolioCB) {
    filterString += 'portfolio-';
  }
  if (this.rentalCB) {
    filterString += 'rental-';
  }
  if (this.emergencyCB) {
    filterString += 'emergency-';
  }

  this.dataService.customerMasterData(filterString, this.order, this.sortDirection, this.datePipe.transform(this.startdate, 'dd-MM-yyyy'), this.datePipe.transform(this.enddate, 'dd-MM-yyyy'), false, this.Globalvariables.emergencyDistance, this.listPage, this.specificTime)
    .subscribe(
      (response: Response) => {
        this.listViewData = response.json();
        this.getMarkers();
        this.listPageCount = Math.ceil(this.listViewData.totalFileViewCount / 50);
        if (this.listPageCount == 0) {
          this.listPageCount = 1;
        }
      },
      (error) => {
        console.log(error);
      }
    )
} else {
//MAP

  let filterString = "";
  if (this.portfolioCB) {
    filterString += 'portfolio-';
  }
  if (this.rentalCB) {
    filterString += 'rental-';
  }
  if (this.emergencyCB) {
    filterString += 'emergency-';
  }

  this.dataService.customerMasterData(filterString, this.order, this.sortDirection, this.datePipe.transform(this.startdate, 'dd-MM-yyyy'), this.datePipe.transform(this.enddate, 'dd-MM-yyyy'), false, this.Globalvariables.emergencyDistance, null, this.specificTime)
    .subscribe(
      (response: Response) => {
        this.listViewData = response.json();
        this.getMarkers();
      },
      (error) => {
        console.log(error);
      }
    )
}}

【问题讨论】:

  • 我相信您只想在从 API 接收数据后执行某些操作,即来自portfolioPolygon、customerMasterData 的数据?
  • 理想情况下,我只想在 ngOnInit() 上链接这些函数。例如,当 getPolygons() 完成时,调用 customerMasterdata(),完成后调用 loadMap() 等,以便在继续之前运行函数中的所有代码。目前,某些 http 请求可能无法在下一个函数预期数据之前完成。

标签: angular http callback observable


【解决方案1】:

你应该使用RxJSmergeMap,它做的事情和你期望的一样。在另一个或链接之后进行一个 http 调用。

在你的情况下,ngOnInit

ngOnInit() {
    this.dataService.portfolioPolygon()
      .map((response: Response) => {
          const data = response.json();
          // Do the rest
          },
       )
     .mergeMap(responseFromPortfolioPolygon => this.dataService.customerMasterData(filterString, this.order, this.sortDirection, this.datePipe.transform(this.startdate, 'dd-MM-yyyy'), this.datePipe.transform(this.enddate, 'dd-MM-yyyy'), false, this.Globalvariables.emergencyDistance, this.listPage, this.specificTime))
      .map(
       (res: Response) => res.json()
       // Do the rest
       )
       .subscribe(res => loadMap()  // CALL LOAD MAP );
}

不要忘记从正确的位置导入mergeMap,因为这在每个RxJS 版本中都会发生变化

import 'rxjs/add/operator/mergeMap';

希望对你有帮助。

【讨论】:

  • 感谢您的回答。我不知道mergeMap。但是对于 customerMasterData 函数(以及其他一些函数),有一些 if 语句可以预先确定如何调用 API。使用 mergeMap 似乎我无法做到这一点。如果我理解正确,也会导致大量重复代码。
猜你喜欢
  • 2017-01-22
  • 2020-11-07
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多