Async y await
Parte de la sección Conceptos básicos de Node.js del Journey de Node.js de Coddy. Lección 23 de 33.
Una cadena de llamadas a .then se lee de forma distinta a como piensas en los pasos: leer, después analizar y después guardar.
Dentro de una función async, await hace una pausa hasta que se resuelve una promesa y te da su valor. Si una promesa falla, lanza un error ahí, así que try y catch lo gestionan. En un módulo, await también funciona en el nivel 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);Una función async siempre devuelve una promesa, así que quien la llama también debe esperarla. Si olvidas un await, obtienes la promesa en sí, Promise { <pending> }, en lugar de su valor.
Desafío
FácilEste paso abre el proyecto preparado de una herramienta de línea de comandos para gestionar notas del curso, en lugar de los archivos de tu proyecto de Promises (incluido count.js). Tu trabajo anterior permanece en su propia lección. Lee los archivos proporcionados antes de editar store.js. Esta copia contiene el lector de notas basado en promesas y su gestión de errores.
store.js ahora usa las versiones basadas en promesas de readFile y writeFile, y sus métodos son async. Pero todavía no se espera a que se resuelvan las promesas, así que todos los comandos fallan. Añade await donde sea necesario esperar a que se resuelva una promesa antes de continuar con el siguiente paso.
- En
store.js, dentro deload, espera a que terminereadFileantes de queJSON.parseuse el texto. - En
store.js,loadesasync, así que devuelve una promesa. Espera a que se resuelva donde el almacén asigna el valor anotes. Un módulo puede usarawaiten el nivel superior, fuera de cualquier función. - En
store.js, espera a que terminewriteFileensave, y espera a que terminethis.save()enaddy enremove. - En
notes.js,store.addystore.removeahora sonasync. Espéralas en las ramasaddydone, para quenyremovedcontengan valores, no promesas.
En total, eso suma siete await. Así, todos los comandos funcionan como antes. list muestra las notas de notes.json. Con las dos notas iniciales, add Buy bread imprime Saved note 3., y después done 1 imprime Done: Buy milk.
Pruébalo: escribe list en el cuadro después de $ node notes.js antes de cambiar nada. Verás notes.json is damaged: ..., pero el archivo está bien: se pasó una promesa a JSON.parse en lugar del texto del archivo. Después de hacer los cambios, list vuelve a mostrar las notas. Luego escribe add Buy bread y verás Saved note 3.. Escribe done 1 y verás Done: Buy milk.
Pruébalo tú mismo
import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';
const file = 'notes.json';
// readFile y writeFile ahora devuelven promesas. Espera cada una 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;
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Conceptos básicos de Node.js
Practica por tu cuenta: Playground de Express