Fui revisando async
/ await
e depois de revisar vários artigos, decidi testar as coisas sozinho. No entanto, não consigo entender por que isso não funciona:
async function main() {
var value = await Promise.resolve('Hey there');
console.log('inside: ' + value);
return value;
}
var text = main();
console.log('outside: ' + text);
O console produz o seguinte (nó v8.6.0):
> fora: [promessa do objeto]
> dentro: Olá
Por que a mensagem de log dentro da função é executada posteriormente? Eu pensei que o motivo async
/ await
foi criado era para executar a execução síncrona usando tarefas assíncronas.
Existe uma maneira de eu usar o valor retornado dentro da função sem usar um .then()
depois main()
?
await
não é nada além de açúcar para athen
sintaxe da promessa .main
async/await
faz parte do ES2017, não do ES7 (ES2016) #Respostas:
Porque
main
retorna uma promessa; todas asasync
funções fazem.No nível superior, você deve:
Use uma
async
função de nível superior que nunca rejeite (a menos que você queira erros de "rejeição sem tratamento") ouUse
then
ecatch
, ou(Em breve!) Use nível superior
await
, uma proposta que atingiu o Estágio 3 no processo que permite o uso de nível superiorawait
em um módulo.# 1 -
async
Função de nível superior que nunca rejeitaObserve o
catch
; você deve lidar com exceções de rejeição de promessa / assíncrono, pois nada mais será necessário; você não tem quem ligar para eles. Se preferir, você pode fazer isso com o resultado da chamada através dacatch
função (em vez detry
/catch
sintaxe):... que é um pouco mais conciso (eu gosto por esse motivo).
Ou, é claro, não lide com erros e permita apenas o erro "rejeição sem tratamento".
# 2 -
then
ecatch
O
catch
manipulador será chamado se ocorrerem erros na cadeia ou no seuthen
manipulador. (Certifique-se de que seucatch
manipulador não gere erros, pois nada está registrado para lidar com eles.)Ou ambos os argumentos para
then
:Mais uma vez, observe que estamos registrando um manipulador de rejeição. Mas, neste formulário, verifique se nenhum dos seus
then
retornos de chamada não gera erros, nada é registrado para lidar com eles.Nível 3
await
em um móduloVocê não pode usar
await
no nível superior de um script que não seja do módulo, mas a proposta de nível superiorawait
( Estágio 3 ) permite usá-lo no nível superior de um módulo. É semelhante ao uso de umasync
wrapper de função de nível superior (nº 1 acima), pois você não deseja que seu código de nível superior rejeite (gere um erro) porque isso resultará em um erro de rejeição sem tratamento. Portanto, a menos que você queira ter essa rejeição sem tratamento quando as coisas derem errado, como no número 1, convém agrupar seu código em um manipulador de erros:Observe que, se você fizer isso, qualquer módulo que importe do seu módulo aguardará até que a promessa que você está fazendo seja
await
estabelecida; quando um módulo usando o nível superiorawait
é avaliado, basicamente retorna uma promessa ao carregador de módulos (como faz umaasync
função), que espera até que a promessa seja estabelecida antes de avaliar os corpos de qualquer módulo que dependa dele.fonte
async
/await
são açúcar sintáticos em torno de promessas (o bom tipo de açúcar :-)). Você não está pensando nisso como retornando uma promessa; realmente faz. ( Detalhes .)async
opções primeiro. Para a função de nível superior, eu posso vê-la de qualquer maneira (principalmente por causa de dois níveis de recuo naasync
versão).await
proposta atingiu Stage 3. :-)O nível superior
await
passou para o estágio 3, portanto, a resposta para sua pergunta Como posso usar o assíncrono / aguardar no nível superior? é apenas adicionarawait
a chamada paramain()
:Ou apenas:
Lembre-se de que ele ainda está disponível apenas no [email protected] .
Se você estiver usando o TypeScript , ele chegou à 3.8 .
A v8 adicionou suporte nos módulos.
Também é suportado por Deno (como comentado por gonzalo-bahamondez).
fonte
A solução real para esse problema é abordá-lo de maneira diferente.
Provavelmente, seu objetivo é algum tipo de inicialização que normalmente ocorre no nível superior de um aplicativo.
A solução é garantir que haja apenas uma única instrução JavaScript no nível superior do seu aplicativo. Se você tiver apenas uma instrução na parte superior do seu aplicativo, poderá usar async / wait em qualquer outro ponto em qualquer lugar (sujeito, é claro, às regras normais de sintaxe)
Dito de outra maneira, envolva todo o seu nível superior em uma função para que ele não seja mais o nível superior e resolva a questão de como executar o assíncrono / aguardar no nível superior de um aplicativo - você não.
É assim que deve ser o nível superior do seu aplicativo:
fonte
application()
seja assíncrono?Para fornecer mais informações sobre as respostas atuais:
O conteúdo de um
node.js
arquivo atualmente é concatenado, de maneira semelhante a uma string, para formar um corpo de função.Por exemplo, se você possui um arquivo
test.js
:Em seguida
node.js
, concatenará secretamente uma função que se parece com:O principal a ser observado é que a função resultante NÃO é uma função assíncrona. Portanto, você não pode usar o termo
await
diretamente dentro dele!Mas digamos que você precise trabalhar com promessas nesse arquivo, então existem dois métodos possíveis:
await
diretamente dentro da funçãoawait
A opção 1 exige a criação de um novo escopo (e ESTE escopo pode ser
async
, porque temos controle sobre ele):A opção 2 exige que usemos a API de promessa orientada a objetos (o paradigma menos bonito, mas igualmente funcional de trabalhar com promessas)
Pessoalmente, espero que, se for viável, o node.js, por padrão, concatene o código em uma
async
função. Isso acabaria com essa dor de cabeça.fonte
A espera de nível superior é um recurso do próximo padrão EcmaScript. Atualmente, você pode começar a usá-lo com o TypeScript 3.8 (na versão RC no momento).
Como instalar o TypeScript 3.8
Você pode começar a usar o TypeScript 3.8 instalando-o no npm usando o seguinte comando:
No momento, você precisa adicionar a
rc
tag para instalar a versão mais recente do TypeScript 3.8.fonte
Como
main()
é executado de forma assíncrona, ele retorna uma promessa. Você precisa obter o resultado nothen()
método E como osthen()
retornos também prometem, você deve ligarprocess.exit()
para encerrar o programa.fonte
exit()
para sinalizar se ocorreu um erro.process.exit(1)