await() de nível superior sem async()⇒{…} em NodeJs

Jan 06 2023
Veja como a função async-await normalmente funciona: Vamos agora falar sobre um cenário diferente: Aqui está outro exemplo do meu arquivo index.js dentro do meu projeto NodeJs em que não coloquei minha chamada await dentro de uma função async (a versão do Node que estou usando é 19.

Veja como a função async-await normalmente funciona:

function myDummyBackendCall() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        name: "Shivang",
        id: "asmdhajkdhajdsh8qweuqoweuiqepoi-0q-0eueiuaisjdaKcjaisku",
      });
    });
  });
}

// Used an async wrapper function to make an await call
(async () => {
  let data = await myDummyBackendCall();
  console.log(data);
})();

Vamos agora falar sobre um cenário diferente:

Aqui está outro exemplo do meu arquivo index.js dentro do meu projeto NodeJs em que não coloquei minha awaitchamada dentro de uma asyncfunção (a versão do Node que estou usando é 19.3.0):

function myDummyBackendCall() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        name: "Shivang",
        id: "asmdhajkdhajdsh8qweuqoweuiqepoi-0q-0eueiuaisjdaKcjaisku",
      });
    });
  });
}

//Note that there is no async wrapper function

let data = await myDummyBackendCall();
console.log(data);

// Output of node index.js
{
  name: 'Shivang',
  id: 'asmdhajkdhajdsh8qweuqoweuiqepoi-0q-0eueiuaisjdaKcjaisku'
}

{
  "name": "src",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type":"module", // I'm here!
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Dentro de um package.json, o “type”valor de “module”diz ao NodeJs para interpretar os arquivos com .jsextensão usando a sintaxe do módulo ES, por exemplo: importdeclaração ou import()expressões.

“type” define como o tempo de execução do NodeJs deve resolver especificadores ou carregar módulos.

Existem dois valores possíveis para “type”config:

  1. módulo
  2. commonjs (padrão)

Aqui está o código de exemplo (sem typeconfiguração):

{
  "name": "src",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Aqui está o código dentro index.mjs(exatamente o mesmo código acima):

function myDummyBackendCall() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        name: "Shivang",
        id: "asmdhajkdhajdsh8qweuqoweuiqepoi-0q-0eueiuaisjdaKcjaisku",
      });
    });
  });
}
  
console.log(await myDummyBackendCall());

Aqui estão alguns pontos direto da documentação oficial do NodeJs :

  1. Os arquivos que terminam com .mjssão sempre carregados como módulos ES, independentemente do pai mais próximo package.json.
  2. Os arquivos que terminam com .cjssão sempre carregados como CommonJS, independentemente do pai mais próximo package.json.

Isso só funciona quando awaita chamada é feita no nível superior dos módulos. Aqui está uma ilustração:

O carregador de módulo ECMAScript é assíncrono . Isso significa que o await de nível superior permite que o módulo atue como uma BIG função assíncrona quando o NodeJs o carrega como ES Module. Portanto, o await de nível superior não precisa de um wrapper de função assíncrona explícita. Isso também significa que um await sem async é um mito!

Isenção de responsabilidade:

Isso é puramente um recurso do NodeJs. Não há conceito de .mjse .cjsno JavaScript vanilla.

Nota de agradecimento ❤️

Obrigado pela visita. Espero que você ache este artigo útil. Se você fizer isso, por favor, siga-me no meio. Isso realmente me encorajará a publicar mais conteúdo.

PS: Se você acha que algo pode ser melhorado ou carece de uma explicação adequada, deixe-me uma nota na caixa de comentários ou envie-me um e-mail para [email protected] . Afinal, você também pode me ensinar uma ou duas coisas.