Async and Await
Part of the Node.js Basics section of Coddy's Node.js journey. Lesson 23 of 33.
A chain of .then calls reads differently from how you think about the steps: read, then parse, then save.
Inside an async function, await pauses until a promise settles and gives you its value. A failed promise throws there, so try and catch handle it. In a module, await also works at the top level.
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);An async function always returns a promise, so its caller awaits it too. Forget an await and you get the promise itself, Promise { <pending> }, instead of its value.
Challenge
EasyThis step opens the course’s prepared notes command-line tool project, rather than your project files from Promises (including count.js). Your earlier work stays in its own lesson. Read the supplied files before editing store.js. This copy contains the promise-based notes reader and its error handling.
store.js now uses the promise versions of readFile and writeFile, and its methods are async. But nothing waits for the promises yet, so every command breaks. Add await wherever a promise must finish before the next step.
- In
store.js, inload, wait forreadFilebeforeJSON.parseuses the text. - In
store.js,loadisasync, so it returns a promise. Wait for it where the store setsnotes. A module may useawaitat the top level, outside any function. - In
store.js, wait forwriteFileinsave, and wait forthis.save()inaddand inremove. - In
notes.js,store.addandstore.removeareasyncnow. Wait for them in theaddanddonebranches, sonandremovedhold values, not promises.
That makes seven awaits in all. Every command then works as before. list shows the notes in notes.json. With the two starting notes, add Buy bread prints Saved note 3., and done 1 then prints Done: Buy milk.
Try it: type list in the box after $ node notes.js before you change anything. You see notes.json is damaged: ..., but the file is fine: JSON.parse was given a promise instead of the file's text. After your changes, list shows the notes again. Then type add Buy bread and see Saved note 3.. Type done 1 and see Done: Buy milk.
Try it yourself
import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';
const file = 'notes.json';
// readFile and writeFile now return promises. Wait for each with 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;
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Node.js Basics
Practice on your own: Express playground