I am currently reading Eloquent JavaScript by Marijn Haverbeke and there is a piece of code that I want someone to explain for me. Consider the following commented code:
class Network {
constructor() {
// irrelevent code except the following line
this.types = Object.create(null)
}
defineRequestType(name, handler) {
this.types[name] = handler
}
}
// when we call the defineRequestType method in another module.
defineRequestType("note", (nest, content, source, done) => {
// this is the callback I am referring to. (See below)
console.log(`${nest.name} received note: ${content}`);
done();
});
// last but not least, the send method
send(to, type, message, callback) {
let toNode = this[$network].nodes[to]
let handler = this[$network].types[type] // this is important. we're referring to the function's callback that we just called, and this callback is our handler
if (!handler) // not important
return callback(new Error("Unknown request type " + type))
if (Math.random() > 0.03) setTimeout(() => {
try {
/*
When we call the send method, the part that I don't understand is that we passed 'done()' as a callback to the handler.
However, as you can see in the previous function call, done() does not take any arguments.
Yet, the handler expects the callback of the handler to have 2 arguments 'error' and 'response'. How is this possible?
*/
handler(toNode, ser(message), this.name, (error, response) => {
setTimeout(() => callback(error, ser(response)), 10)
})
} catch(e) {
callback(e)
}
}, 10 + Math.floor(Math.random() * 10))
}
In case you are interested in reading the source code, please take a look at the this link were you will find the above functions and more (quite sophisticated) functions. Please click on crow tech and Chapter 11 to see the full code. (In case requested).

