await仅在异步函数中有效-使用mongoosejs exec()时 [英] await is only valid in async function - when using mongoosejs exec()

查看:542
本文介绍了await仅在异步函数中有效-使用mongoosejs exec()时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Hapi项目移植到v17,并在迁移到异步/等待时遇到Mongoose的一些问题.

I am porting a Hapi project to v17 and running into some issues with Mongoose when moving to async/await.

例如,对于我在模型(猫鼬)上使用'await'的任何代码,对象:

With any of my code that uses 'await', on a model (mongoose), object for example:

const result = await User.findOne({email: email}).exec();

运行"node server.js"时出现以下异常

I get the following exception when running 'node server.js'

            await User.findOne({}).exec();
        ^^^^^

SyntaxError: await is only valid in async function
at new Script (vm.js:74:7)
at createScript (vm.js:246:10)
at Object.runInThisContext (vm.js:298:10)
at Module._compile (internal/modules/cjs/loader.js:670:28)
at Object.Module._extensions..js 
(internal/modules/cjs/loader.js:713:10)
at Module.load (internal/modules/cjs/loader.js:612:32)
at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
at Function.Module._load (internal/modules/cjs/loader.js:543:3)
at Module.require (internal/modules/cjs/loader.js:650:17)
at require (internal/modules/cjs/helpers.js:20:18)

我正在运行节点v10.2.0和mongoose 5.1.2,无法理解为什么收到错误消息.

I am running node v10.2.0 and mongoose 5.1.2 and cannot understand why I am getting the error.

mongoosejs文档明确指出,使用async/await时,应使用exec()返回诺言,如所述

The mongoosejs documentation clearly states that one should use exec() to return the promise when using async/await as stated here

有什么建议吗?

推荐答案

await仅可在用async关键字声明的函数中使用.

await can only be used INSIDE a function that is declared with the async keyword.

async function doSomething() {
    let result = await someMongoooseFunctionThatReturnsAPromise();
    // use result here
}

await不能在async函数外部使用.那就是你的错误告诉你的,它与猫鼬完全没有关系.它与调用猫鼬功能的代码结构有关.

await cannot be used outside an async function. That's what your error is telling you and it has nothing to do with mongoose at all. It has to do with the structure of YOUR code that is calling the mongoose function.

注意:函数中已经存在任何node.js事件驱动的代码,因此要在该函数中使用await,您要做的就是将async关键字添加到包含以下内容的关键字中函数定义.如果该函数的调用者不希望返回任何结果,则不需要进一步的更改.如果该函数的调用者期望返回结果,则必须调整调用代码以期望从async声明的函数返回承诺.

NOTE: Any node.js event driven code is ALREADY inside a function so to use await in that function, all you have to do is to add the async keyword to that containing function definition. If the caller of that function is not expecting any return result, then no further changes are required. If the caller of that funcition is expecting a return result, then you have to adapt the calling code to expect a promise to be returned from the async declared function.

async函数总是返回一个承诺也是值得理解的.尽管您可以像常规顺序代码一样编写它:

It's also worth understanding that an async function ALWAYS returns a promise. While you may write it like regular sequential code:

async function doSomething() {
    let result = await someMongoooseFunctionThatReturnsAPromise();
    // use result here
    result++;
    return result;
}

此函数实际上是在返回一个诺言,该诺言的解析值将是该函数的返回值.因此,当您使用这样的async函数时,必须使用返回的promise:

This function is actually returning a promise and the resolved value of that promise will be the return value of the function. So, when you use an async function like this, you have to use the returned promise:

 doSomething().then(finalResult => {
     console.log(finalResult);
 });


因此,在您的特定代码中,如果要使用await,则它必须位于async函数内部:


So, in your specific code, if you're going to use await, it needs to be inside an async function:

async function someFunc() {
    const result = await User.findOne({email: email}).exec();
    // now this will work and you can use result here
}

或者,您可以改用.then():

User.findOne({email: email}).exec().then(result => {
    // process result here
    // continue with other code that uses result here
});


注意:要处理使用async/await时的错误,您有两种选择:


NOTE: To handle errors when using async/await, you have two choices:

  1. 您可以在任何async声明的函数中使用传统的try/catch,并且try/catch将捕获来自await的所有拒绝的诺言.

  1. You can use traditional try/catch inside any async declared function and the try/catch will catch any rejected promises from await.

如果您不使用try/catch并且函数内部的await被拒绝,则函数本身返回的承诺将被拒绝,并且函数的调用者将获得被拒绝的承诺. p>

If you don't use try/catch and an await inside your function rejects, then the promise that the function itself returns will become rejected and the caller of your function will get the rejected promise.

因此,这取决于情况.如果要在本地处理拒绝,则必须在await周围使用try/catch(就像使用.catch()一样.)如果希望拒绝冒泡到调用方,以便他们看到被拒绝的诺言,则您不需要try/catch,因为Javascript解释器将通过拒绝async函数返回的承诺来自动冒泡被拒绝的await.

So, it depends upon the situation. If you want to handle a rejection locally, then you must use try/catch around await (much like you would with .catch(). If you want the rejecting to bubble up to the caller so they will see the rejected promise, then you don't need the try/catch as the Javascript interpreter will automatically bubble a rejected await by rejecting the promise that the async function returns.

这篇关于await仅在异步函数中有效-使用mongoosejs exec()时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆