在内部抛出.then块和在异步等待块之间有什么区别



我得到这个错误:

(node:9868) UnhandledPromiseRejectionWarning: #<Object>
(node:9868) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9868) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code

我正在用看起来像这样的express错误处理程序包装create方法:

export const errorHandler = (callback: any) => {
return (req: Request, res: Response, next: NextFunction) => {
callback(req, res, next).catch(next);
};
};

当我尝试这样做时:

async create(entity: T){
this._model
.findOne({ name: (entity as any).name })
.then((res) => {
if (res) {
throw Exceptions.ENTITY_EXISTS; // doesnt work 
}
})
}

然而,当我将其更改为异步等待时,它运行良好

async create(entity: T) {
const res = await this._model.findOne({ name: (entity as any).name });
if (res) throw Exceptions.ENTITY_EXISTS;
}

此外,当我尝试执行而不是抛出Promise.reject(Exceptions.ENTITY_EXISTS)时,它抛出了相同的错误。

有人能解释一下这三者之间的区别吗,以及为什么只有异步等待有效?

区别确实在于throw发生的位置。在工作版本中,它将create()返回的承诺设置为已拒绝。

在非工作版本中,它使.then()返回的承诺被视为已拒绝。然而,这个承诺不是create()返回的承诺,因此即使您正确处理了create()上的拒绝。。。无法处理then()承诺中发生的拒绝。他们没有联系,所以你无法处理这种拒绝。

要修复第一个版本,请确保返回.then():返回的promise

create(entity: T){
return this._model
//  ^^^^^^
.findOne({ name: (entity as any).name })
.then((res) => {
if (res) {
throw Exceptions.ENTITY_EXISTS; // doesnt work 
}
});
}

注意:虽然你可以在函数之前保留async,但如果你不使用await并返回promise,它就没有那么有用了。

NB2:由于缺少returncreate函数实际上返回了一个立即解决的promise。。。因此它从未等待数据库查询。

最新更新