mongoose findById的async/await行为

Men*_*des 4 javascript asynchronous mongoose async-await

我有以下代码:

const checkForRecord = async (id) => {

    let model = mongoose.model('User');

    let query = {}
    query.dummy = false; <== This is field is here to forcely cause an error, as it is not present on my User model.
    let result = await model.findById(id, query);

    console.log('Code reached here !!!');
    console.log(result);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

(node:6680) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): CastError: Cast to ObjectId failed for value ...
Run Code Online (Sandbox Code Playgroud)

console.log甚至没有被召唤.

为什么这个错误没有被设置为结果,因为我的操作是异步的?

我试过了两个:

let result = await model.findById(id, query);
Run Code Online (Sandbox Code Playgroud)

let result = await model.findById(id, query).exec();
Run Code Online (Sandbox Code Playgroud)

相同的行为.

T.J*_*der 7

我的console.logs甚至没有被调用.

这是正确的行为.这是一个async功能,你是awaiting一个返回承诺的功能.这意味着拒绝被建模为异常,终止该checkForRecord功能.

为什么这个错误没有被设置为result,因为我的操作是异步的?

因为它不是分辨率值(这是await给你的),所以它是拒绝/异常.它可能有助于了解checkForRecord看起来像什么样的脱糖,取代async以及await它们潜在的承诺操作:

// checkForRecord with async/await desugared to their underyling Promise operations
const checkForRecord = (id) => {

    let model = mongoose.model('User');

    let query = {};
    query.dummy = false; // <== To cause an error, this field is not used
    return model.findById(id, query).then(value => {
        let result = value;
        console.log('Code reached here !!!');
        console.log(result);
    });
};
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,你没有得到console.logs,因为他们在一个解析处理程序中; 但拒绝不会转到解决方案处理程序,它会转到拒绝处理程序.

要明确:我不是说你需要改变checkForRecord.我只是向你展示运行时async/ await变为(实际上)的内容.

checkForRecord很好(除了缺失=>,没有评论的query.dummy评论).你可以在async函数中使用它:

try {
    checkForRecord(someId);
} catch (e) {
    // Handle the error here
}
Run Code Online (Sandbox Code Playgroud)

...或者如果不在async函数中那么喜欢:

checkForRecord(someId).catch(e => {
    // Handle the error here
});
Run Code Online (Sandbox Code Playgroud)