使用 Typeorm 查询的 forEach 中不允许使用异步函数
Async function not allowed in forEach with Typeorm query
我正在尝试根据对象的元素执行 Typeorm 查询,但我遇到了 forEach
和异步函数的问题。
我已经阅读了很多类似的问题,但没有人按预期为我工作。
这是我的代码片段,在 forEach
:
中不允许等待
public async runBudgetLimit(): Promise<void> {
const contracts: ContractEntity[] = await this.contractService.getAllProjects();
contracts.forEach((contract) => {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
});
}
这是异步 Typeorm 查询:
async findOne(id: string): Promise<UserEntity | undefined> {
return this.userRepository.findOne(id);
}
我不知道解决此问题的最佳解决方案是什么,我认为 for 循环不是一个好的解决方案,但我对所有解决方案持开放态度。
您可以像这样使用 for-of
循环:
for (const contract of contracts) {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
}
或略微优化 - for-of
和 Promise.all
方法之间的差异:
await Promise.all(contracts.map(async contract => {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
}));
请记住,这些解决方案在某些情况下并不是最优的,因为通过为每个合同获取 UserEntity,就会对数据库 AKA N+1 query problem
进行额外的查询。要解决此问题,您可以使用 relations 数组加载所有用户以及合同。
我不确定你为什么从项目中得到 contractId
,它在 contract
对象上不可用吗?
此外,如果 getBillingByProject
的回复是一个承诺,您应该将 await
放在前面
我正在尝试根据对象的元素执行 Typeorm 查询,但我遇到了 forEach
和异步函数的问题。
我已经阅读了很多类似的问题,但没有人按预期为我工作。
这是我的代码片段,在 forEach
:
public async runBudgetLimit(): Promise<void> {
const contracts: ContractEntity[] = await this.contractService.getAllProjects();
contracts.forEach((contract) => {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
});
}
这是异步 Typeorm 查询:
async findOne(id: string): Promise<UserEntity | undefined> {
return this.userRepository.findOne(id);
}
我不知道解决此问题的最佳解决方案是什么,我认为 for 循环不是一个好的解决方案,但我对所有解决方案持开放态度。
您可以像这样使用 for-of
循环:
for (const contract of contracts) {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
}
或略微优化 - for-of
和 Promise.all
方法之间的差异:
await Promise.all(contracts.map(async contract => {
const project: UserEntity = await this.userService.findOne(contract.milestoneId);
const date: string = Time.moment().format('YYYY-MM-DD');
const budgetUsed = this.trackService.getBillingByProject(project.contractId, date, '1000', '1000', true);
}));
请记住,这些解决方案在某些情况下并不是最优的,因为通过为每个合同获取 UserEntity,就会对数据库 AKA N+1 query problem
进行额外的查询。要解决此问题,您可以使用 relations 数组加载所有用户以及合同。
我不确定你为什么从项目中得到 contractId
,它在 contract
对象上不可用吗?
此外,如果 getBillingByProject
的回复是一个承诺,您应该将 await
放在前面