await 仅在异步函数中有效 - 使用 mongoosejs exec() 时
await is only valid in async function - when using mongoosejs exec()
我正在将一个 Hapi 项目移植到 v17,并且 运行 在迁移到 async/await 时遇到一些 Mongoose 问题。
我的任何使用 'await' 的代码,在模型(猫鼬)上,例如对象:
const result = await User.findOne({email: email}).exec();
当 运行 '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)
我是 运行 node v10.2.0 和 mongoose 5.1.2,无法理解为什么会出现错误。
mongoosejs 文档明确指出,在使用 async/await 时应使用 exec() 来 return 承诺 here
有什么建议吗?
您需要像这样用异步函数包围您的代码
async function fetchFun() {
const result = await User.findOne({email: email}).exec();
console.log('Results fetched!'); //etc
}
fetchFun(); // <--
注意: 你仍然需要在没有 await
的情况下调用这个函数,正如我用箭头指出的那样,因为你的代码必须有一些入口 async/await 代码(如 C 中的 main()
)并且入口函数不能用 await
调用
await
只能在使用 async
关键字声明的函数内部使用。
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
}
await
不能在 async
函数之外使用。这就是你的错误告诉你的,它与猫鼬完全无关。它与调用 mongoose 函数的代码结构有关。
注意:任何node.js事件驱动的代码已经在一个函数中,所以要在那个函数中使用await
,你所要做的就是将 async
关键字添加到包含函数定义的关键字中。如果该函数的调用者不期望任何 return 结果,则不需要进一步更改。如果该函数的调用者期望 return 结果,那么您必须调整调用代码以期望从 async
声明的函数中 returned 承诺。
还值得理解的是,async
函数总是 return 是一个承诺。虽然您可以像常规顺序代码一样编写它:
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
result++;
return result;
}
此函数实际上是 return 承诺,该承诺的解析值将是函数的 return 值。所以,当你像这样使用 async
函数时,你必须使用 returned promise:
doSomething().then(finalResult => {
console.log(finalResult);
});
因此,在您的特定代码中,如果您要使用 await
,它需要在 async
函数中:
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
时处理错误,您有两个选择:
您可以在任何 async
声明的函数中使用传统的 try/catch
并且 try/catch
将捕获来自 await
.[=38 的任何被拒绝的承诺=]
如果您不使用 try/catch 并且函数内部的 await
被拒绝,那么函数本身 return 的承诺将被拒绝并且你的函数的调用者将得到被拒绝的承诺。
所以,这要视情况而定。如果你想在本地处理拒绝,那么你必须在 await
周围使用 try/catch(就像你使用 .catch()
一样)。如果你希望拒绝冒泡到调用者,那么他们会看到被拒绝的承诺,那么你不需要 try/catch
因为 Javascript 解释器会通过拒绝 async
函数 [=75] 的承诺来自动冒泡被拒绝的 await
=]s.
我正在将一个 Hapi 项目移植到 v17,并且 运行 在迁移到 async/await 时遇到一些 Mongoose 问题。
我的任何使用 'await' 的代码,在模型(猫鼬)上,例如对象:
const result = await User.findOne({email: email}).exec();
当 运行 '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)
我是 运行 node v10.2.0 和 mongoose 5.1.2,无法理解为什么会出现错误。
mongoosejs 文档明确指出,在使用 async/await 时应使用 exec() 来 return 承诺 here
有什么建议吗?
您需要像这样用异步函数包围您的代码
async function fetchFun() {
const result = await User.findOne({email: email}).exec();
console.log('Results fetched!'); //etc
}
fetchFun(); // <--
注意: 你仍然需要在没有 await
的情况下调用这个函数,正如我用箭头指出的那样,因为你的代码必须有一些入口 async/await 代码(如 C 中的 main()
)并且入口函数不能用 await
await
只能在使用 async
关键字声明的函数内部使用。
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
}
await
不能在 async
函数之外使用。这就是你的错误告诉你的,它与猫鼬完全无关。它与调用 mongoose 函数的代码结构有关。
注意:任何node.js事件驱动的代码已经在一个函数中,所以要在那个函数中使用await
,你所要做的就是将 async
关键字添加到包含函数定义的关键字中。如果该函数的调用者不期望任何 return 结果,则不需要进一步更改。如果该函数的调用者期望 return 结果,那么您必须调整调用代码以期望从 async
声明的函数中 returned 承诺。
还值得理解的是,async
函数总是 return 是一个承诺。虽然您可以像常规顺序代码一样编写它:
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
result++;
return result;
}
此函数实际上是 return 承诺,该承诺的解析值将是函数的 return 值。所以,当你像这样使用 async
函数时,你必须使用 returned promise:
doSomething().then(finalResult => {
console.log(finalResult);
});
因此,在您的特定代码中,如果您要使用 await
,它需要在 async
函数中:
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
时处理错误,您有两个选择:
您可以在任何
async
声明的函数中使用传统的try/catch
并且try/catch
将捕获来自await
.[=38 的任何被拒绝的承诺=]如果您不使用 try/catch 并且函数内部的
await
被拒绝,那么函数本身 return 的承诺将被拒绝并且你的函数的调用者将得到被拒绝的承诺。
所以,这要视情况而定。如果你想在本地处理拒绝,那么你必须在 await
周围使用 try/catch(就像你使用 .catch()
一样)。如果你希望拒绝冒泡到调用者,那么他们会看到被拒绝的承诺,那么你不需要 try/catch
因为 Javascript 解释器会通过拒绝 async
函数 [=75] 的承诺来自动冒泡被拒绝的 await
=]s.