[英]Proper error pattern for async functions using Promises in TypeScript
I want to make a typed async function with proper error handling. 我想使用正确的错误处理来创建一个类型化的异步函数。
I can define one like this: 我可以这样定义一个:
export async function doSomething(userId:string) : Promise<ISomething | void> {
let somthing: ISomething = {};
try {
something.user = await UserDocument.findById(userId);
something.pet = await PetDocument.findOne({ownerId:userId});
return Promise.resolve(something);
} catch (err){
console.log("I would do some stuff here but I also want to have the caller get the error.");
return Promise.reject(err);
}
}
...which seems to work, but (for reasons that are clear), if I try to assign the result to an ISomething
object, I get the error Type 'void | ISomething' is not assignable to type 'ISomething'
...似乎工作,但(由于明确的原因),如果我尝试将结果分配给
ISomething
对象,我得到错误Type 'void | ISomething' is not assignable to type 'ISomething'
Type 'void | ISomething' is not assignable to type 'ISomething'
. Type 'void | ISomething' is not assignable to type 'ISomething'
。
let iSomething:ISomething;
iSomething = await doSomething('12'); //this give me the error
I get why that is. 我知道那是为什么。 My question is, what pattern should I use for error handling in a case like this?
我的问题是,在这样的情况下,我应该使用什么模式进行错误处理? Note that if the return type is
Promise<IProfile>
instead then I get an error for the return Promise.reject(err);
请注意,如果返回类型是
Promise<IProfile>
那么我收到return Promise.reject(err);
line (which would return Profile<void>
). line(将返回
Profile<void>
)。
In place of the line return Promise.reject(err);
代替行
return Promise.reject(err);
I can use throw err;
我可以用
throw err;
, but there may be times where I'd want to use the Promise.reject
pattern (like if I want to do some more things before I return). ,但有时我可能会想要使用
Promise.reject
模式(就像我想在返回之前做更多的事情)。
I have a feeling that I'm missing something with promises / async, but I can't find typed examples that follow this pattern. 我有一种感觉,我错过了promises / async的东西,但我找不到遵循这种模式的类型示例。
...note that if I use the full Promise pattern it works fine: ...请注意,如果我使用完整的Promise模式,它可以正常工作:
doSomething('12')
.then( (something) => {//do stuff})
.catch( (err) => {//handle error});
Should I just be using throw
and forget about Promise.reject
? 我应该只使用
throw
并忘记Promise.reject
吗? If I use throw
, will the .catch()
be triggered appropriately? 如果我使用
throw
,是否会正确触发.catch()
?
Not returning a promise in the first place is how I usually implement the async await pattern: 首先不返回promise是我通常如何实现异步await模式:
export async function doSomething(userId:string) : Promise<ISomething>{
let something: ISomething = {};
try {
something.user = await UserDocument.findById(userId);
something.pet = await PetDocument.findOne({ownerId:userId});
return something;
} catch (err){
console.log("I would do some stuff here but I also want to have the caller get the error.");
throw(err);
}
}
so if you don't have to do intermediate cleanup you could strip it down to: 因此,如果您不需要进行中间清理,可以将其剥离为:
export async function doSomething(userId:string) : Promise<ISomething>{
let something: ISomething = {};
something.user = await UserDocument.findById(userId);
something.pet = await PetDocument.findOne({ownerId:userId});
return something;
}
and have 并有
the subsequent awaited function catch the exception or 随后等待的函数捕获异常或
the calling function handle the rejected promise 调用函数处理被拒绝的承诺
All fair if you don't want to use Promise.reject
and Promise.resolve
, but if you do - here's the easy fix. 如果你不想使用
Promise.reject
和Promise.resolve
那么Promise.resolve
,但是如果你这样做 - 这就是简单的解决方法。
Get rid of the | void
摆脱
| void
| void
in the signature, and change the rejection returned to return Promise.reject<ISomething>(err);
签名中为
| void
,并更改返回的拒绝返回return Promise.reject<ISomething>(err);
. 。 Works!
作品!
Here's the modified version from the question: 以下是问题的修改版本:
export async function doSomething(userId:string) : Promise<ISomething> {
let something: ISomething = {};
try {
something.user = await UserDocument.findById(userId);
something.pet = await PetDocument.findOne({ownerId:userId});
return Promise.resolve(something);
} catch (err){
console.log("I would do some stuff here but I also want to have the caller get the error.");
return Promise.reject<ISomething>(err);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.