【发布时间】:2021-12-12 14:04:00
【问题描述】:
我正在为用户资源创建一个带有 CRUD 操作的 API。因为 TypeORM 在将创建的用户插入数据库后不会返回它,所以我执行了一个“findOne”请求以提供用户名来取回它。
为了做到这一点,我使用 QueryRunner 在我的 UserService 中创建了一个事务。它看起来像这样:
控制器
@Post()
create(@Body() user: User) {
return this.userService
.createUser(user)
.then((user) => {
return user;
})
.catch(() => {
throw new InternalServerErrorException('Could not create user');
});
}
服务
createUser(user: User): Promise<User | void> {
const queryRunner = this.connection.createQueryRunner();
return queryRunner
.connect()
.then(() => {
queryRunner
.startTransaction()
.then(() => {
queryRunner.manager
.save(User, user)
.then((user) => {
queryRunner.manager
.findOne(User, {
username: user.username,
})
.then((user) => {
queryRunner
.commitTransaction()
.then(() => {
return Promise.resolve(user);
})
.catch((error) => {
console.log('Could not commit transaction : ', error);
return Promise.reject();
});
})
.catch((error) => {
console.log(
`Could not get user after insert, username : ${user.username}, error : ${error}`,
);
return Promise.reject();
});
})
.catch((error) => {
console.log(
'Could not insert user into the database : ',
error,
);
queryRunner
.rollbackTransaction()
.then(() => {
console.log('Rolled back transaction');
return Promise.resolve();
})
.catch((error) => {
console.log('Could not rollback transaction : ', error);
return Promise.reject();
});
});
})
.catch((error) => {
console.log('Could not start transaction : ', error);
return Promise.reject();
});
})
.catch((error) => {
console.log('Could not connect to database : ', error);
return Promise.reject();
})
.finally(() => {
queryRunner
.release()
.then((user) => {
console.log('Released query runner for User transaction');
return Promise.resolve(user);
})
.catch((error) => {
console.log('Could not release queryRunner : ', error);
return Promise.reject();
});
});
}
这段代码有很多问题,我知道,但我是 javascript 世界的新手,不知道如何做得更好:
- 我查看了互联网,有人将我正在做的事情(嵌套承诺)称为末日金字塔,这是一种反模式,但我不知道该怎么做。
- 当我运行我的代码并请求创建用户时,finally() 块在 then() 之前被调用,因此在我执行我的事务之前释放我的 queryRunner。谁能告诉我为什么?
- 为了解决这个问题,我删除了 finally() 并在 then() 和 catch() 中进行了释放,但后来发生的事情是我的函数在调用“startTransaction”后返回并且没有执行 then()之前,所以发生的情况是我在完成我的 UserService 函数 (createUser) 之前返回控制器并向用户返回响应。
我希望您有足够的信息来帮助我,但如果需要,我很乐意添加更多详细信息。
谢谢,
【问题讨论】:
-
您通常可以通过使用链式 Promise 来避免嵌套的 Promise,或者您也可以切换到
async/await语法。
标签: javascript typescript promise nestjs typeorm