How does a node.js process know when to stop?
Since many node.js scripts follow a pattern of doing something asynchronously (example below), how do they know when to stop?
In the following code, how does node determine after processing the writeFile, and registering the callback appropriately, that the process should be kept alive until the callback(s) run?
fs = require('fs');
fs.writeFile('foo', 'cat', function() {
console.log('wrote to foo!');
fs.readFile('foo', 'utf8', function(err, data) {
console.log(data);
});
});
Solution 1:
node keeps track of all outstanding work requests. Your fs.writefile() call creates a work request for I/O and adds your callback to that request. node saves the work request into its tables at the same time it is starting the I/O activity. Your code execution exits when you reach the end of your function. (But your memory/variables/etc. remain)
Later the I/O finishes and node takes the work request out of its tables. It sees the callback attached to the request and so calls that function with the results of the I/O request. Your global data is still around and any variables in closures still exist, so it seems to your code like it never stopped.
If you do nothing more, don't make any more requests, then when you return from your functions node will stop, because then there won't be any remaining requests in the queues.
So node 'knows' to keep running because it tracks active work requests in its tables and won't stop until all queued work is done and those tables are empty.
Please note that "queued work" can include things like waiting for timers or waiting for network data to arrive. You make a request that says "call me here when/if something happens later".
setTimeout() is a work request too (if you squint a bit). With a timer you know something will happen and when it will happen. With setTimeout() only one 'something' will happen. node will make only one call to your callback and then 'forget' the work request. If instead you use setInterval() you have created a persistent work request. node will 'keep' the work request in its tables and will call your callback repeatedly, until you cancel the request.
net.Server.listen() is another work request which is a persistent work request. You don't know when your callback will be called or how many times, because that depends on remote clients connecting to your server. node keeps the work request alive in its tables until you cancel the request.