Javascript 在TypeScript中使用承诺的异步函数的正确错误模式

Javascript 在TypeScript中使用承诺的异步函数的正确错误模式,javascript,node.js,typescript,promise,async-await,Javascript,Node.js,Typescript,Promise,Async Await,我想创建一个具有正确错误处理的类型化异步函数 我可以这样定义: export async function doSomething(userId:string) : Promise<ISomething | void> { let somthing: ISomething = {}; try { something.user = await UserDocument.findById(userId); something.pet =

我想创建一个具有正确错误处理的类型化异步函数

我可以这样定义:

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);
    }
}
我明白这是为什么。我的问题是,在这种情况下,我应该使用什么模式来处理错误?请注意,如果返回类型为
Promise
,则返回Promise.reject(err)会出现错误行(将返回
Profile

代替行
返回承诺。拒绝(err)我可以使用
抛出错误
,但有时我可能想使用
Promise.reject
模式(例如,如果我想在返回之前做更多的事情)

我觉得我缺少了Promissions/async,但我找不到遵循这种模式的类型化示例

…请注意,如果我使用完整承诺模式,它可以正常工作:

doSomething('12')
  .then( (something) => {//do stuff})
  .catch( (err) => {//handle error});

我应该仅仅使用
抛出
而忘记
承诺。拒绝
?如果我使用
throw
,是否会正确触发
.catch()

首先不返回承诺是我通常实现异步等待模式的方式:

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);
    }
}
导出异步函数doSomething(userId:string):Promise{
让某物:等轴物={};
试一试{
something.user=await UserDocument.findById(userId);
something.pet=等待PetDocument.findOne({ownerId:userId});
归还某物;
}捕捉(错误){
log(“我会在这里做一些事情,但我也想让调用者得到错误。”);
抛出(错误);
}
}
因此,如果您不必进行中间清理,您可以将其拆分为:

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;
}
导出异步函数doSomething(userId:string):Promise{
让某物:等轴物={};
something.user=await UserDocument.findById(userId);
something.pet=等待PetDocument.findOne({ownerId:userId});
归还某物;
}
而且

  • 后续等待的函数捕获异常或

  • 调用函数处理被拒绝的承诺


如果你不想使用
承诺,那么一切都是公平的。拒绝
承诺。解决
,但如果你这样做了-这里有一个简单的解决方法

去掉签名中的
| void
,将退回的拒绝更改为
退回承诺。拒绝(err)。工作

以下是问题的修改版本:

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);
    }
}
导出异步函数doSomething(userId:string):Promise{
让某物:等轴物={};
试一试{
something.user=await UserDocument.findById(userId);
something.pet=等待PetDocument.findOne({ownerId:userId});
回报承诺。决心(某事);
}捕捉(错误){
log(“我会在这里做一些事情,但我也想让调用者得到错误。”);
退回承诺。拒绝(错误);
}
}

…我已经回答了部分问题:“如果我使用throw,会正确触发.catch()吗?”-是的,编写一些测试代码表明会触发。我猜抛出的错误在异步函数中会变成拒绝的承诺。我仍然很想知道在这种情况下如何使用Promise.reject(特别是我在打字错误方面的问题)。关键是你可以使用
throw
。请使用
throw
,因为您所拥有的是一个非常混乱的模式组合。我不同意这是一个模式组合-必须使用
throw
并返回承诺更像是一个模式组合。使用Promise.resolve和Promise.reject似乎是对模式的一致使用。
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);
    }
}