Menu
CoddyTech

Async e await

Fa parte della sezione Fondamenti di Node.js del percorso Node.js di Coddy. Lezione 23 di 33.

Una catena di chiamate a .then si legge diversamente da come pensi ai passaggi: leggere, poi analizzare, poi salvare.

All'interno di una funzione async, await sospende l'esecuzione finché una promise non si risolve e te ne restituisce il valore. Una promise rifiutata genera un'eccezione in quel punto, quindi try e catch la gestiscono. In un modulo, await funziona anche al livello superiore.

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);

Una funzione async restituisce sempre una promise, quindi anche chi la chiama deve usare await. Dimentica un await e otterrai la promise stessa, Promise { <pending> }, invece del suo valore.

challenge icon

Sfida

Facile

Questo passaggio apre il progetto dello strumento da riga di comando per le note preparato per il corso, anziché i file del tuo progetto di Promises (incluso count.js). Il lavoro precedente rimane nella sua lezione. Leggi i file forniti prima di modificare store.js. Questa copia contiene il lettore di note basato sulle promise e la relativa gestione degli errori.

store.js ora usa le versioni basate sulle promise di readFile e writeFile, e i suoi metodi sono async. Ma per ora nessuno attende le promise, quindi ogni comando non funziona. Aggiungi await ovunque una promise debba completarsi prima del passaggio successivo.

  1. In store.js, dentro load, attendi che readFile termini prima che JSON.parse usi il testo.
  2. In store.js, load è async, quindi restituisce una promise. Attendi che termini nel punto in cui lo store imposta notes. Un modulo può usare await al livello superiore, fuori da qualsiasi funzione.
  3. In store.js, attendi che writeFile termini in save, e attendi che this.save() termini in add e in remove.
  4. In notes.js, store.add e store.remove ora sono async. Attendi che terminino nei rami add e done, così n e removed contengono valori, non promise.

In tutto, servono sette await. A quel punto ogni comando funziona come prima. list mostra le note in notes.json. Con le due note iniziali, add Buy bread stampa Saved note 3., e poi done 1 stampa Done: Buy milk.

Prova: digita list nella casella dopo $ node notes.js prima di apportare modifiche. Vedrai notes.json is damaged: ..., ma il file è a posto: a JSON.parse è stata passata una promise invece del testo del file. Dopo le modifiche, list mostrerà di nuovo le note. Poi digita add Buy bread e vedrai Saved note 3.. Digita done 1 e vedrai Done: Buy milk.

Provalo tu

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

const file = 'notes.json';

// readFile e writeFile ora restituiscono promise. Attendi ciascuna con 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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Fondamenti di Node.js

Esercitati da solo: Playground Express