Eu escrevi este código em lib/helper.js
var myfunction = async function(x,y) {
....
reutrn [variableA, variableB]
}
exports.myfunction = myfunction;
e então tentei usá-lo em outro arquivo
var helper = require('./helper.js');
var start = function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Eu tenho um erro
"await só é válido na função assíncrona"
Qual é o problema?
javascript
node.js
j.doe
fonte
fonte
await
só pode ser usado dentro de umaasync
função. Ou seja,await
torna uma função assíncrona, por isso deve ser declarada como tal.Respostas:
O erro não está se referindo a,
myfunction
mas astart
.Eu uso a oportunidade desta questão de aconselhá-lo sobre um anti padrão conhecido usando
await
o que é:return await
.ERRADO
CORRIGIR
Além disso, saiba que há um caso especial em que
return await
é correto e importante: (usando try / catch)Existem preocupações de desempenho com `return await`?
fonte
start
como umaasync
função (embora alguns optem por fazê-lo de qualquer maneira, para ser mais explícito)Quando recebi esse erro, descobri que havia uma chamada para a função map dentro da minha função "assíncrona", então essa mensagem de erro estava se referindo à função de mapa não estar marcada como "assíncrona". Eu resolvi esse problema pegando a chamada "esperar" da função de mapa e descobrindo alguma outra maneira de obter o comportamento esperado.
fonte
someArray.map(async (someVariable) => { return await someFunction(someVariable)})
await
em seu código é enganoso, porqueArray.map
não tratará a função como uma função assíncrona. Para ficar bem claro, após a conclusão damap
função,someFunction
tudo estará pendente. Se você quiser realmente esperar que as funções terminem, você deve escrever:await Promise.all(someArray.map(someVariable => someFunction(someVariable)))
ouawait Promise.all(someArray.map(someFunction)))
.Para usar
await
, seu contexto de execução precisa estarasync
na naturezaComo disse, você precisa definir a natureza de
executing context
onde você está disposto aawait
uma tarefa antes de qualquer coisa.Basta colocar
async
antes dafn
declaração na qual suaasync
tarefa será executada.Explicação:
Na sua pergunta, você está importando um
method
que estáasynchronous
na natureza e será executado em paralelo. Mas onde você está tentando executar esseasync
método está dentro de um diferenteexecution context
que você precisa definirasync
para usarawait
.Querendo saber o que está acontecendo sob o capô
await
consome métodos / funções de promessa / futuro / retorno de tarefa easync
marca um método / função como capaz de usar o await.Além disso, se você estiver familiarizado com o
promises
,await
está realmente fazendo o mesmo processo de promessa / resolução. Criar uma cadeia de promessas e executar a próxima tarefa noresolve
retorno de chamada.Para obter mais informações, você pode consultar o MDN DOCS .
fonte
A implementação atual de
async
/await
suporta apenas aawait
palavra - chave dentro dasasync
funções. Altere astart
assinatura da função para que você possa usarawait
dentrostart
.Para os interessados, a proposta de nível superior
await
está atualmente na Etapa 2: https://github.com/tc39/proposal-top-level-awaitfonte
async
- que é o todo ponto deasync
.--experimental-repl-await
opção.Eu tive o mesmo problema e o seguinte bloco de código estava apresentando a mesma mensagem de erro:
O problema é que o método getCommits () era assíncrono, mas eu estava passando para ele o argumento repo, que também foi produzido por uma Promise. Então, eu tive que adicionar a palavra async a ele assim: async (repo) e ele começou a funcionar:
fonte
async / await é o mecanismo de manipulação de promessa, duas maneiras de fazer isso
ou podemos usar await para aguardar a promessa de preenchimento completo primeiro, o que significa que foi rejeitada ou resolvida.
Agora, se quisermos usar await (aguardando o cumprimento de uma promessa) dentro de uma função, é obrigatório que a função de contêiner seja uma função assíncrona porque estamos aguardando que uma promessa seja cumprida de forma assíncrona || faz sentido certo ?.
fonte
"await só é válido na função assíncrona"
Mas por que? 'await' transforma explicitamente uma chamada assíncrona em uma chamada síncrona e, portanto, o chamador não pode ser assíncrono (ou asyncable) - pelo menos, não por causa da chamada sendo feita em 'await'.
fonte
Sim, await / async era um ótimo conceito, mas a implementação está completamente quebrada.
Por algum motivo, a palavra-chave await foi implementada de forma que só pode ser usada em um método assíncrono. Na verdade, isso é um bug, embora você não vá vê-lo referido como tal em nenhum lugar, exceto aqui. A correção para esse bug seria implementar a palavra-chave await de forma que ela só pudesse ser usada PARA CALL uma função assíncrona, independentemente de a própria função de chamada ser síncrona ou assíncrona.
Devido a esse bug, se você usar await para chamar uma função assíncrona real em algum lugar do código, TODAS as funções devem ser marcadas como assíncronas e TODAS as chamadas de função devem usar await.
Isso significa essencialmente que você deve adicionar a sobrecarga de promessas a todas as funções em todo o seu aplicativo, a maioria das quais não são e nunca serão assíncronas.
Se você realmente pensar sobre isso, o uso de await em uma função deve exigir a função que contém a palavra-chave await TO NOT BE ASYNC - isso ocorre porque a palavra-chave await vai pausar o processamento na função onde a palavra-chave await é encontrada. Se o processamento nessa função for pausado, então definitivamente NÃO é assíncrono.
Portanto, para os desenvolvedores de javascript e ECMAScript - corrija a implementação de await / async como segue ...
fonte
async
isso reflete o fato de que muitas de suas funções requerem os resultados de processos externos. Isso é completamente canônico na minha opinião.await
para ser utilizável apenas com chamadas de função: para um único processo externo, apenas um único ponto no código javascript pode ser notificado quando esse processo for concluído. Por exemplo, se o conteúdo de um arquivo for necessário para 3 finalidades independentes, cada finalidade precisaria realizar de forma independentelet content = await readTheFile();
- isso ocorre porque a "promessa do conteúdo do arquivo" não pode ser esperada, apenas "o ato de ler o arquivo e retomar uma vez que tenha sido ler".