TypeScript - 等待嵌套 for 循环完成
TypeScript - waiting for nested for loops to complete
我有两个 for 循环,一个嵌套在另一个循环中。第一个循环进行 API 调用。它将根据用户选择的 ID 数量执行。我无法一次将多个 ID 传递给 API。嵌套循环将为 API 返回的每个对象 运行 并将数据添加到数组中。我的最终目标是将所有数据放在一个数组中,并使用@Input() 将该数组传递给子组件。我已经研究并尝试使用 Promise 来做到这一点,但仍然不太正确。我希望子组件中的 ngOnChanges() 仅在返回所有数据后执行 - 即两个 for 循环都已完成执行。这就是我所做的:
父组件:
getData() {
let temp: MyObjectType[] = [];
let allDataToSend: MyObjectType[] = [];
return new Promise<MyObjectType[]>((resolve, reject) => {
for (let i = 0; i < this.userIdSelections.length; i++) {
this.dataService.getData(this.userIdSelections[i])
.subscribe(results => temp = results,
error => {
this.getRequestResult = <any>error;
},
() => {
for (let j = 0; j < temp.length; j++) {
allDataToSend.push({
Property1: temp[j].Property1,
Property2: temp[j].Property2,
Property3: temp[j].Property3,
Property4: temp[j].Property4,
});
}
}
);
}
resolve(allDataToSend);
});
}
finalResults() {
this.getData().then(response => {
this.FinalObjectSendToChild = response;
})
}
父模板:
<button mat-flat-button color="primary" (click)="finalResults()">Search</button>
<app-child [finalData]="FinalObjectSendToChild"></app-child>
子组件:
export class ChildComponent implements OnChanges {
@Input() finalData: MyObjectType[];
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
public tableColumns = ['Property1', 'Property2', 'Property3', 'Property4'];
public tableData: any
constructor() { }
ngOnChanges(changes: SimpleChanges) {
if (changes.finalData) this.createTable();
}
createTable() {
console.log(this.finalData); // this will show all of the data the way I would expect
console.log(this.finalData.length); // however, this always returns 0
// the table created is blank...
this.tableData = new MatTableDataSource(this.finalData);
this.tableData.sort = this.sort;
this.tableData.paginator = this.paginator;
}
您可以使用 Promise.All:
(...)
for (let i = 0; i < this.userIdSelections.length; i++) {
arrayPromises.push(this.dataService.getData(this.userIdSelections[i]).toPromise());
}
Promise.all(arrayPromises).then((values) => {
const allDataToSend = [];
for(let value of values) {
for (let j = 0; j < value.length; j++) {
allDataToSend.push({
Property1: value[j].Property1,
Property2: value[j].Property2,
Property3: value[j].Property3,
Property4: value[j].Property4,
});
}
}
resolve(allDataToSend);
});
(...)
我有两个 for 循环,一个嵌套在另一个循环中。第一个循环进行 API 调用。它将根据用户选择的 ID 数量执行。我无法一次将多个 ID 传递给 API。嵌套循环将为 API 返回的每个对象 运行 并将数据添加到数组中。我的最终目标是将所有数据放在一个数组中,并使用@Input() 将该数组传递给子组件。我已经研究并尝试使用 Promise 来做到这一点,但仍然不太正确。我希望子组件中的 ngOnChanges() 仅在返回所有数据后执行 - 即两个 for 循环都已完成执行。这就是我所做的:
父组件:
getData() {
let temp: MyObjectType[] = [];
let allDataToSend: MyObjectType[] = [];
return new Promise<MyObjectType[]>((resolve, reject) => {
for (let i = 0; i < this.userIdSelections.length; i++) {
this.dataService.getData(this.userIdSelections[i])
.subscribe(results => temp = results,
error => {
this.getRequestResult = <any>error;
},
() => {
for (let j = 0; j < temp.length; j++) {
allDataToSend.push({
Property1: temp[j].Property1,
Property2: temp[j].Property2,
Property3: temp[j].Property3,
Property4: temp[j].Property4,
});
}
}
);
}
resolve(allDataToSend);
});
}
finalResults() {
this.getData().then(response => {
this.FinalObjectSendToChild = response;
})
}
父模板:
<button mat-flat-button color="primary" (click)="finalResults()">Search</button>
<app-child [finalData]="FinalObjectSendToChild"></app-child>
子组件:
export class ChildComponent implements OnChanges {
@Input() finalData: MyObjectType[];
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
public tableColumns = ['Property1', 'Property2', 'Property3', 'Property4'];
public tableData: any
constructor() { }
ngOnChanges(changes: SimpleChanges) {
if (changes.finalData) this.createTable();
}
createTable() {
console.log(this.finalData); // this will show all of the data the way I would expect
console.log(this.finalData.length); // however, this always returns 0
// the table created is blank...
this.tableData = new MatTableDataSource(this.finalData);
this.tableData.sort = this.sort;
this.tableData.paginator = this.paginator;
}
您可以使用 Promise.All:
(...)
for (let i = 0; i < this.userIdSelections.length; i++) {
arrayPromises.push(this.dataService.getData(this.userIdSelections[i]).toPromise());
}
Promise.all(arrayPromises).then((values) => {
const allDataToSend = [];
for(let value of values) {
for (let j = 0; j < value.length; j++) {
allDataToSend.push({
Property1: value[j].Property1,
Property2: value[j].Property2,
Property3: value[j].Property3,
Property4: value[j].Property4,
});
}
}
resolve(allDataToSend);
});
(...)