Before the lab
Background
Callback Chaining
- Time
- 25 minutes
- Activity
- Code puzzle.
The recommended way to get maximimum performance from the node.js filesystem API is to use callbacks, i.e. functions to call when the I/O operation completes.
Replace the ALL-CAPITALS words in the following code sample with defined identifiers to make this callback chaining example work.
const fs=require("node:fs");
function log(string, next) {
let date = new Date();
function finish(err) {
if (err) throw err;
console.timeEnd("write");
CALLBACK();
}
function write(err, fd) {
if (err) throw err;
fs.write(VALUE, date.toISOString() + ": " + string, CALLBACK);
}
console.time("write");
fs.open("log.txt", "a", CALLBACK)
}
console.time("log");
log("first\n",
() => {
log("second\n",
() => console.log("done"));
});
console.timeEnd("log");
When you get the code working, the file log.txt
should contain lines
like the following (the exact date and time may differ):
2024-10-25T17:31:56.626Z: first
2024-10-25T17:31:56.629Z: second
Questions for your journal:
- Why are the functions
write
andfinish
defined insidelog
? - What can you tell about the execution order from the printed output?
- Based on the printed timings, does it make sense to use asynchronous I/O to write a single string to a file?
Promises
- Time
- 25 minutes
- Activity
- Code puzzle, reading documentation
In the Promises
API
file system methods return a Promise object that automates the
chaining of callbacks. These Promise objects can be chained together
using then
. Fill in the appropriate API calls (they should be very
similar to the first part, without the explicit callbacks).
const fs=require("node:fs/promises");
function log(string) {
let date = new Date();
return new Promise(next=> {
console.time("write");
API_CALL
.then(fd=>API_CALL)
.then(()=>console.timeEnd("write"))
.then(CALLBACK)
.catch((err) => console.log(err));
});
}
console.time("log");
log("first\n")
.then(()=>log("second\n"))
.catch((err) => console.log(err));
console.timeEnd("log");
Questions for your journal:
According to the NodeJS Documentation, what is one disadvantage of the Promises API?
What does the
Promise.catch
method do?
Async Functions
- Time
- 25 minutes
- Activity
- Code puzzle, reading book
Async Functions provide some nice features for programming with Promises, essentially eliminating some of the boilerplate from our previous example. They also introduce one very important keyword.
Replace the ALL-CAPITALS parts of the following program to duplicate the functionality of the previous versions.
const fs=require("node:fs/promises");
async function log(string) {
console.time("write")
const fd = MAGIC_KEYWORD API_CALL()
let date = new Date();
const promise=API_CALL();
console.timeEnd("write");
return promise;
}
console.time("log");
log("first\n")
.then(()=>log("second\n"))
.catch((err) => console.log(err));
console.timeEnd("log");
- What is the keyword used as MAGIC_KEYWORD above, and what does it do?
Before Next Lab
Read
Practical Python on Testing (mainly the part on
pytest
, at the end).