Javascript await 仅在 async 函数中有效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49432579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
await is only valid in async function
提问by j.doe
I wrote this code in lib/helper.js
我写了这段代码 lib/helper.js
var myfunction = async function(x,y) {
....
reutrn [variableA, variableB]
}
exports.myfunction = myfunction;
and then I tried to use it in another file
然后我尝试在另一个文件中使用它
var helper = require('./helper.js');
var start = function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
I got an error
我有一个错误
"await is only valid in async function"
“await 仅在异步函数中有效”
What is the issue?
问题是什么?
回答by Grégory NEUT
The error is not refering to myfunctionbut to start.
错误不是指myfunction而是指start。
async function start() {
....
const result = await helper.myfunction('test', 'test');
}
// My function
const myfunction = async function(x, y) {
return [
x,
y,
];
}
// Start function
const start = async function(a, b) {
const result = await myfunction('test', 'test');
console.log(result);
}
// Call start
start();
I use the opportunity of this question to advise you about an known anti pattern using awaitwhich is : return await.
我利用这个问题的机会向您介绍一种已知的反模式,使用的await是 : return await。
WRONG
错误的
async function myfunction() {
console.log('Inside of myfunction');
}
// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later
// useless async here
async function start() {
// useless await here
return await myfunction();
}
// Call start
(async() => {
console.log('before start');
await start();
console.log('after start');
})();
CORRECT
正确的
async function myfunction() {
console.log('Inside of myfunction');
}
// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later
// Also point that we don't use async keyword on the function because
// we can simply returns the promise returned by myfunction
function start() {
return myfunction();
}
// Call start
(async() => {
console.log('before start');
await start();
console.log('after start');
})();
回答by John Langford
When I got this error, it turned out I had a call to the map function inside my "async" function, so this error message was actually referring to the map function not being marked as "async". I got around this issue by taking the "await" call out of the map function and coming up with some other way of getting the expected behavior.
当我收到此错误时,结果证明我在“async”函数中调用了 map 函数,因此此错误消息实际上是指未将 map 函数标记为“async”。我通过从 map 函数中取出“await”调用并提出其他一些获得预期行为的方法来解决这个问题。
var myfunction = async function(x,y) {
....
someArray.map(someVariable => { // <- This was the function giving the error
return await someFunction(someVariable);
});
}
回答by Satyam Pathak
To use await, its executing context needs to be asyncin nature
要使用await,它的执行上下文需要async在本质上
As it said, you need to define the nature of your executing contextwhere you are willing to awaita task before anything.
正如它所说,在做任何事情之前,您需要先定义executing context您愿意执行await任务的性质。
Just put asyncbefore the fndeclaration in which your asynctask will execute.
只需放在您的任务将在其中执行async的fn声明之前async。
var start = async function(a, b) {
// Your async task will execute with await
await foo()
console.log('I will execute after foo get either resolved/rejected')
}
Explanation:
解释:
In your question, you are importing a methodwhich is asynchronousin nature and will execute in parallel. But where you are trying to execute that asyncmethod is inside a different execution contextwhich you need to define asyncto use await.
在你的问题,你导入的是method这是asynchronous在本质上,将并行执行。但是您尝试执行该async方法的位置位于execution context您需要定义async以使用的不同方法中await。
var helper = require('./helper.js');
var start = async function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Wondering what's going under the hood
想知道引擎盖下发生了什么
awaitconsumes promise/future / task-returning methods/functions and asyncmarks a method/function as capable of using await.
await消耗承诺/未来/任务返回方法/函数并将方法/函数async标记为能够使用等待。
Also if you are familiar with promises, awaitis actually doing the same process of promise/resolve. Creating a chain of promise and executes you next task in resolvecallback.
此外,如果您熟悉promises,await实际上正在执行相同的承诺/解决过程。创建一个承诺链并在resolve回调中执行你的下一个任务。
For more info you can refer to MDN DOCS.
有关更多信息,您可以参考MDN 文档。
回答by user835611
The current implementation of async/ awaitonly supports the awaitkeyword inside of asyncfunctions Change your startfunction signature so you can use awaitinside start.
async/的当前实现await仅支持函数await内的关键字async更改您的start函数签名,以便您可以使用awaitinside start。
var start = async function(a, b) {
}
For those interested, the proposal for top-level awaitis currently in Stage 2: https://github.com/tc39/proposal-top-level-await
对于那些有兴趣的人,顶级提案await目前处于第 2 阶段:https: //github.com/tc39/proposal-top-level-await
回答by Emil
I had the same problem and the following block of code was giving the same error message:
我遇到了同样的问题,以下代码块给出了相同的错误消息:
repositories.forEach( repo => {
const commits = await getCommits(repo);
displayCommit(commits);
});
The problem is that the method getCommits() was async but I was passing it the argument repo which was also produced by a Promise. So, I had to add the word async to it like this: async(repo) and it started working:
问题是 getCommits() 方法是异步的,但我将参数 repo 传递给它,该参数也是由 Promise 生成的。所以,我不得不像这样添加 async 这个词:async(repo) 然后它开始工作:
repositories.forEach( async(repo) => {
const commits = await getCommits(repo);
displayCommit(commits);
});
回答by mn_test347
"await is only valid in async function"
“await 仅在异步函数中有效”
But why? 'await' explicitly turns an async call into a synchronous call, and therefore the caller cannot be async (or asyncable) - at least, not because of the call being made at 'await'.
但为什么?'await' 显式地将异步调用转换为同步调用,因此调用者不能是异步的(或可异步的)——至少,不是因为调用是在 'await' 进行的。
回答by Rodney P. Barbati
Yes, await / async was a great concept, but the implementation is completely broken.
是的,await / async 是一个很棒的概念,但是实现完全被破坏了。
For whatever reason, the await keyword has been implemented such that it can only be used within an async method. This is in fact a bug, though you will not see it referred to as such anywhere but right here. The fix for this bug would be to implement the await keyword such that it can only be used TO CALL an async function, regardless of whether the calling function is itself synchronous or asynchronous.
无论出于何种原因,已经实现了 await 关键字,以便它只能在异步方法中使用。这实际上是一个错误,尽管您不会在任何地方看到它,但就在此处。修复此错误的方法是实现 await 关键字,使其只能用于调用异步函数,而不管调用函数本身是同步的还是异步的。
Due to this bug, if you use await to call a real asynchronous function somewhere in your code, then ALL of your functions must be marked as async and ALL of your function calls must use await.
由于此错误,如果您使用 await 在代码中的某处调用真正的异步函数,那么您的所有函数都必须标记为 async,并且您的所有函数调用都必须使用 await。
This essentially means that you must add the overhead of promises to all of the functions in your entire application, most of which are not and never will be asynchronous.
这实质上意味着您必须向整个应用程序中的所有函数添加 promise 的开销,其中大多数不是也永远不会是异步的。
If you actually think about it, using await in a function should require the function containing the await keyword TO NOT BE ASYNC - this is because the await keyword is going to pause processing in the function where the await keyword is found. If processing in that function is paused, then it is definitely NOT asynchronous.
如果您真的考虑一下,在函数中使用 await 应该要求包含 await 关键字的函数不能异步 - 这是因为 await 关键字将在找到 await 关键字的函数中暂停处理。如果该函数中的处理被暂停,那么它绝对不是异步的。
So, to the developers of javascript and ECMAScript - please fix the await/async implementation as follows...
因此,对于 javascript 和 ECMAScript 的开发人员 - 请按如下方式修复 await/async 实现......
- await can only be used to CALL async functions.
- await can appear in any kind of function, synchronous or asynchronous.
- Change the error message from "await is only valid in async function" to "await can only be used to call async functions".
- await 只能用于调用异步函数。
- await 可以出现在任何类型的函数中,同步或异步。
- 将错误信息从“await 仅在异步函数中有效”更改为“await 只能用于调用异步函数”。

