使用Typeorm查询的forEach中不允许使用异步功能

问题描述

我正在尝试根据对象的元素进行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',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',true);
        }

或稍作优化-check this answer用于解决for-ofPromise.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,true);
        }));

请记住,这些解决方案在某些情况下不是最佳的,因为通过获取每个合同的UserEntity,将对数据库AKA N+1 query problem进行附加查询。要解决此问题,您可以使用relations数组来加载所有用户以及合同。

我不确定您为什么从项目中获得contractId,在contract对象上不可用吗?

如果getBillingByProject的答复是一个承诺,您应该将await放在前面

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...