如何在 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()
时尚未设置,因此 firstDataSource
和 secondDataSource
永远不会通过对 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 将按执行顺序将所有结果包含在一个数组中。
您应该使用 Promise
和 Then
或 async 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),
);
我必须在 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()
时尚未设置,因此 firstDataSource
和 secondDataSource
永远不会通过对 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 将按执行顺序将所有结果包含在一个数组中。
您应该使用 Promise
和 Then
或 async 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),
);