0

Is the following a statement of best practices in Node.js with regard to web applications? If not, how could it be improved?

The statement

The lifecycle of any web app has at least two phases: a setup phase, and a ready phase (when the application is ready to respond to requests.)

In the ready phase,

  1. IO operations (disk access, database calls, etc.) should always be asynchronous/non-blocking.

  2. Even operations that occur purely in memory should be asynchronous, when possible. This is especially true when the operations involve iteration, and especially^2 true when the upper limit on the number of iterations is unknown.

  3. Synchronous/blocking operations should never be performed in response to a request.

In my opinion, the question of whether or not something is part of the best practices for developing in a certain programming language can be answered decisively based on experience and objective criteria.

3

The answer as someone who has written a significant amount of node.js code at a professional level is yes. As a JavaScript implementation there is no notion of a thread in Node.js. All IO operations are therefore asynchronous. While many of the common node lower level api's do provide an xxxSync variant using them is not preferred and can cause noticeable performance problems, even under very low load, and development conditions.

With regard to your comment about in memory operations. No in memory operations are truly asynchronous. While it is common to reuse the callback pattern when implementing long lived functions this is more a convention than anything else. In order for a function to be asynchronous it must release it's hold on the processor. In standard languages a system call blocks, meaning that although the process is no longer in charge of the processor, and the process itself is in wait state, other parts of the same program cannot be executed. In node asynchronous callbacks perform the same task that threads do in most languages by allowing the program to proceed although one of it's operations is in wait state.

Long story short, always use async when possible but understand the difference between using the callback pattern and using an actual async operation while they often look identical in the code they are drastically different. Misunderstanding the difference can cause some real headaches for people new to the language.

  • What I had in mind for (2) was something like the following: you have an array of strings. You're running through the array, using a regular expression on each item to find a match. This all occurs in memory, but if you use a regular for loop, you will block any other operations from happening in the application. Is that correct? – Terrence Sep 2 '14 at 16:38
  • Yes, you would be blocking, but since you only have one thread there's no opportunity for anything else to start happening in parallel. Even if you implemented your function to take a callback when it finishes it still wouldn't be asynchronous. – john-charles Sep 2 '14 at 16:41
  • What if I made my code invoke a function between processing each item in the array? I get that things would not be happening in parallel, but if the code in the function that is sandwiched between each turn of the iteration HAS to happen (i.e. it's my request handler, or whatever) shouldn't my for loop do as much as it can to yield to it? – Terrence Sep 2 '14 at 17:00
  • I'm not sure I know exactly what you mean. But yes, node has an internal event loop, so your request handler would typically be implemented as a callback passed in when you start your server. With that being said if your in complex code you can force it to become (sort of) asynchronous by causing it to sleep. setTimeout(fn, time) will yield the stack and allow the event loop to take over. In that case you could yield the stack after parsing each element in the array. But now we're in the realm of what feels more and more like premature optimization. – john-charles Sep 2 '14 at 17:13
  • Well, in the real world, I'd probably use something like the async library (the each function), or an array of promises, to get the job done. Presumably, on some level, they're doing something like nextTick() or setTimeout(), yes? – Terrence Sep 2 '14 at 17:55
0

I respond not by experience, but because of what I have read a lot of time in blogs of node js competent developpers : Yes these are good rules since it seems all whom have passed performance test agree that blocking calls are the main cause of performance dropping.

There is an exemple but i've read a least twelve agreeing with when looking for information about node js.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.