Node.js Basics: JavaScript Outside the Browser
Files and Async Code
In this lesson you will
- Read and write files with fs/promises
- Explain asynchronous code and why Node uses it
- Handle errors with try and catch around await
Introduction
Reading a file or calling a network takes time compared with running code. If a program stopped and waited every time, it would be slow. Node is built around asynchronous code: start a job, carry on, and handle the result when it is ready.
Reading and writing files
The fs/promises module returns promises, which work with async and await:
"hello\nworld\n"
2writeFilecreates or replaces a file. Be careful not to overwrite something you need.readFilewith"utf8"gives you text. Without it you get raw bytes.awaitpauses this function until the promise finishes, without blocking the rest of the program.- Top-level
awaitworks in ES modules.
Other useful functions include appendFile to add to the end, readdir to list a folder, mkdir to make folders and rm to remove files. Use rm with great care.
Building safe file paths
Use the path module instead of gluing strings together:
On Linux and macOS, path.join uses /. On Windows it uses \. It also handles extra slashes for you. Never build a path directly from user input without checking it, because someone could use ../ to reach other folders.
Quick quiz
What does await do in an async function?
Handling errors
Files can be missing, locked or unreadable. Use try and catch:
ENOENT means "no such file or directory". Check the code for the cases you expect, and rethrow others so real problems are not hidden.
Why async?
Imagine a restaurant with one waiter. If the waiter stood at the kitchen door until each dish was ready, nobody else would be served. Instead the waiter takes an order, moves on, and returns when the kitchen rings. Node works like that waiter, which is why one Node process can handle thousands of connections.
Three styles exist, all doing the same job:
- Callbacks: the original style, which can become deeply nested
- Promises: objects representing a future result, with
.then() - async and await: promises written like normal code, which is the style to prefer
Doing several things at once
Start independent jobs together and wait for all of them:
If one fails, Promise.all rejects. Use Promise.allSettled when you want every result, success or failure.
Try it yourself
Write a script that reads a text file given on the command line, counts its lines and words, prints the results, and prints a friendly message if the file does not exist.
Summary
fs/promisesreads and writes files, andpathbuilds file paths safely.- Asynchronous code lets Node keep working while it waits, and
asyncwithawaitmakes it readable. - Use try and catch, check error codes such as ENOENT, and use Promise.all for independent jobs.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading