mongoose findById的async / await行为

时间:2017-11-01 11:56:33

标签: 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);
}

我收到以下错误:

(node:6680) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): CastError: Cast to ObjectId failed for value ...

我的console.log甚至没有被调用。

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

我试过了两个:

let result = await model.findById(id, query);

let result = await model.findById(id, query).exec();

同样的行为。

1 个答案:

答案 0 :(得分:6)

  

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

这是正确的行为。这是一个async函数,你是awaiting函数返回一个promise。这意味着拒绝被建模为例外,终止checkForRecord功能。

  

为什么该错误未设置为result,因为我的操作是异步的?

因为它不是分辨率值(这是await给你的),所以它是拒绝/异常。可能有助于查看checkForRecord的脱糖情况,将asyncawait替换为潜在的承诺操作:

// 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);
    });
};

正如您所看到的,您没有到达console.log,因为他们在解决方案处理程序中;但拒绝不会转到解决方案处理程序,它会转到拒绝处理程序。

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

您的checkForRecord没问题(除了缺少=>而没有对query.dummy行发表评论)。你可以在async函数中使用它:

try {
    checkForRecord(someId);
} catch (e) {
    // Handle the error here
}

...或者如果不在async函数中那么这样:

checkForRecord(someId).catch(e => {
    // Handle the error here
});