如何在 Angular 中的另一个方法之后同步调用方法?

How to synchronically call methods after another method in Angular?

我必须在 ngOnInit() 方法中同步调用一些方法,但它们都从内部对 API 进行了一些异步调用。第一种方法中设置了一些变量,第二种和第三种方法需要这些变量已经设置。我不能使用 rxjs 映射运算符(mergeMap、switchMap、concatMap、exhaustMap),因为调用是由进行其他操作的单独方法进行的。

这是我的:

public taskTypes: any; // variable to be setted in first method
public firstDataSource: any;
public secondDataSource: any;
// some other variables to be setted in first method

constructor(...) {
  this.taskTypes = [];
  this.firstDataSource = [];
  this.secondDataSource = [];
  // some other initializations
}

ngOnInit() {
  this.getTaskTypes();
  this.methodOne();
  this.methodTwo()
}

public getTaskTypes(): void {
  this.http.get("url").subscribe(
    (res) => {
      this.taskTypes = res.tasks;
      // some other operations with response data
      // and set other variables
    },
    (err) => {}
  );
  // some other operations with variables
}

public methodOne(): void {
  if (this.taskTypes.length > 0) {
    this.http.get("url/" + 1).subscribe(
      (res) => {
        this.firstDataSource = res.data;
      },
      (err) => {}
    );
  }
  // some other operations with variables
}

public methodTwo(): void {
  if (this.taskTypes.length > 0) {
    this.http.get("url/" + 2).subscribe(
      (res) => {
        this.secondDataSource = res.data;
      },
      (err) => {}
    );
  }
  // some other operations with variables
}

我的问题是,在调用 ngOnInit() 时,同时调用了所有内部方法,条件的结果:this.taskTypes.length > 0 始终是 false,因为变量taskTypes 在调用 methodOne()methodTwo() 时尚未设置,因此 firstDataSourcesecondDataSource 永远不会通过对 API。这就是为什么我需要在 getTaskTypes().

之后同步调用 methodOne()methodTwo()

首先将您的方法更改为 return 仅可观察,例如

public getTaskTypes():Observable<any> {
 return this.http.get("url");
}

然后用concat依次执行,用toArray()把结果转成数组

 concat(this.getTaskTypes(),this.methodOne(),this.methodTwo())
 .pipe(toArray()).subscribe(res=>console.log(res))

res 将按执行顺序将所有结果包含在一个数组中。

您应该使用 PromiseThenasync await 的概念。例如,你的 ngOnInit 应该是这样的:

async ngOnInit() {
  await this.getTaskTypes();
  await this.methodOne();
  await this.methodTwo()
}

通过使用 await,methodOne 将等待 getTaskTypes 被解析。但请记住,await 仅在您的函数 return 是 Promise 或 Observable 时才有效。在这种情况下,因为您的函数没有 return 任何东西,所以 await 将不起作用。因此,例如 getTaskTypes 应该是这样的:

public async getTaskTypes(){
  return new Promise(resolve, reject) => {
      this.http.get("url").subscribe(
      (res) => {
        this.taskTypes = res.tasks;
        resolve();
        // some other operations with response data
        // and set other variables
      },
      (err) => {
        reject(err);
      }
    );
    // some other operations with variables
  });
}

当然有更好的方法来解决这个问题,但我试图让你理解主要思想。您可以在 here.

中阅读更多相关信息

当然你可以用 rxjs 做到这一点

this.http.get("url").pipe(
    map(res => res.tasks),
    filter(taskTypes => taskTypes.length > 0),
    switchMap(taskTypes => combineLatest([this.http.get("url/" + 1), this.http.get("url/" + 2)])),
  ).subscribe(
   ([methodOneResult, methodTwoResult]) => console.log(methodOneResult, methodTwoResult),
  );

这里有一个例子:https://stackblitz.com/edit/angular-jevauk