问题描述
我正在将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:
-
您可以在任何
async
声明的函数中使用传统的try/catch
,并且try/catch
将捕获来自await
的所有拒绝的诺言.
You can use traditional
try/catch
inside anyasync
declared function and thetry/catch
will catch any rejected promises fromawait
.
如果您不使用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()时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!