Menu
CoddyTech

Async e await

Parte da seção Fundamentos de Node.js do Journey de Node.js da Coddy. Lição 23 de 33.

Uma cadeia de chamadas .then tem uma ordem diferente daquela em que você pensa nas etapas: ler, depois analisar e, então, salvar.

Dentro de uma função async, await pausa a execução até que uma promise seja resolvida ou rejeitada e fornece o valor dela. Uma promise rejeitada lança um erro nesse ponto, então try e catch tratam disso. Em um módulo, await também funciona no nível superior.

import { readFile } from 'node:fs/promises';

const loadConfig = async () => {
    try {
        return JSON.parse(await readFile('config.json', 'utf8'));
    } catch {
        return {};
    }
};

const config = await loadConfig();
console.log(config.port ?? 3000);

Uma função async sempre retorna uma promise, então quem a chama também precisa usar await. Esqueça um await e você obtém a própria promise, Promise { <pending> }, em vez do valor dela.

challenge icon

Desafio

Fácil

Esta etapa abre o projeto da ferramenta de linha de comando de notas preparada para o curso, em vez dos arquivos do seu projeto de Promises (incluindo count.js). Seu trabalho anterior permanece na própria lição. Leia os arquivos fornecidos antes de editar store.js. Esta cópia contém o leitor de notas baseado em promises e seu tratamento de erros.

store.js agora usa as versões baseadas em promises de readFile e writeFile, e seus métodos são async. Mas nada espera pelas promises ainda, então todos os comandos falham. Adicione await onde for necessário esperar uma promise terminar antes da próxima etapa.

  1. Em store.js, dentro de load, espere por readFile antes que JSON.parse use o texto.
  2. Em store.js, load é async, então retorna uma promise. Espere por ela onde o armazenamento define notes. Um módulo pode usar await no nível superior, fora de qualquer função.
  3. Em store.js, espere por writeFile em save e espere por this.save() em add e em remove.
  4. Em notes.js, store.add e store.remove agora são async. Espere por elas nas ramificações add e done, para que n e removed contenham valores, não promises.

Isso totaliza sete awaits. Então, todos os comandos funcionam como antes. list mostra as notas em notes.json. Com as duas notas iniciais, add Buy bread exibe Saved note 3., e done 1 exibe Done: Buy milk.

Experimente: digite list na caixa após $ node notes.js antes de mudar qualquer coisa. Você verá notes.json is damaged: ..., mas o arquivo está correto: JSON.parse recebeu uma promise em vez do texto do arquivo. Depois das alterações, list mostra as notas novamente. Em seguida, digite add Buy bread e veja Saved note 3.. Digite done 1 e veja Done: Buy milk.

Experimente você mesmo

import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';

const file = 'notes.json';

// readFile e writeFile agora retornam promessas. Aguarde cada uma com await.
const load = async () => {
    if (!existsSync(file)) {
        return [];
    }
    try {
        return JSON.parse(readFile(file, 'utf8'));
    } catch (err) {
        console.error(`notes.json is damaged: ${err.message}`);
        process.exit(1);
    }
};

const store = {
    notes: load(),
    async save() {
        writeFile(file, JSON.stringify(this.notes, null, 2));
    },
    async add(text) {
        this.notes.push(text);
        this.save();
        return this.notes.length;
    },
    async remove(n) {
        const [text] = this.notes.splice(n - 1, 1);
        this.save();
        return text;
    },
};

export default store;
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Fundamentos de Node.js

Pratique por conta própria: Playground de Express