Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prescriptive Node.js

I've been starting to play around with Node.js recently and I've come across a situation where I need a little guidance around the prescriptive node.js way of accomplishing a task. In this particular case I need to create a bunch of directories and, when all of the directories have been created I need to perform some final operation. The order in which the directories are created does not matter, I just need to perform a final operation after the last one is.

The easiest way the accomplish this would be to fall back to the old synchronous habits. That is, just call fs.mkdirSync for each of the directories and perform the operation at the end. For example:

fs.mkdirSync('a', 0755); fs.mkdirSync('a/b', 0755); fs.mkdirSync('a/b/c', 0755); performFinalOperation(); 

While this would work, it doesn't feel like it's the node.js way of doing it. Obviously, the program would block while it waits for the OS to create the directory and return. On a heavily loaded system with a file system that's mounted remotely each of the mkdirSync calls could take a very long time. So clearly, this isn't the best approach.

One of Node.js main selling points is the fact that it's asynchronous. So the calls to fs.mkdir could be chained through the callbacks:

fs.mkdir('a', 0755, function(e) {     if (!e) {         fs.mkdir('a/b', 0755, function(e) {             if (!e) {                 fs.mkdir('a/b/c', 0755, function(e) {                     if (!e) {                         performFinalOperation();                     }                 });             }         });     } }); 

Again, this approach I'm sure works, but it leads to really deep nesting and code duplication. It does have the benefit of not blocking while the directories are created, but at what cost?

Another approach would be to get really fancy in an effort to avoid the code duplication and nesting:

(function (directories) {     if (directories.length === 0) {         performFinalOperation();     } else {         var tail = arguments.callee;         fs.mkdir(directories.shift(), 0755, function(e) {             tail(directories);         });     } })(['a', 'a/b', 'a/b/c']); 

This approach makes use of all sorts of crazy stuff: anonymous self calling functions and the magical arguments.callee. But worst of all, it isn't obvious what the code is doing at first glance.

So, while the concrete question is around creating directories I'm more interested in the approach that a seasoned node.js veteran would take when this sort of situation arises. I'm specifically not interested in what libraries are around to make this easier.

like image 624
Bryan Kyle Avatar asked Mar 15 '11 07:03

Bryan Kyle


People also ask

Does Netflix use node JS?

Netflix initially used Node. js to enable high volume web streaming to over 182 million subscribers. Their three goals with this early infrastructure was to provide observability (metrics), debuggability (diagnostic tools) and availability (service registration). The result was the NodeQuark infrastructure.

Can I use type script for Node JS?

TypeScript is well-established in the Node. js world and used by many companies, open-source projects, tools and frameworks. Some of the notable examples of open-source projects using TypeScript are: NestJS - robust and fully-featured framework that makes creating scalable and well-architected systems easy and pleasant.

CAN node js handle high traffic?

In this article, we will consider some practices that you should adopt to scale your Node. js servers. Your servers will then be able to handle high traffic workloads without a degraded user experience.

CAN node js be used as frontend?

Yes, Node. js can be used in both the frontend and backend of applications.


1 Answers

Your second solution can be greatly simplified, and include errors like this:

var mkdirs = function(dirs, mode, cb){   (function next(e) {     (!e && dirs.length) ? fs.mkdir(dirs.shift(), mode, next) : cb(e);   })(null); }; 
like image 172
Adrien Avatar answered Oct 06 '22 05:10

Adrien