• The original
  • The author

NodeJS you don’t know about

Update: This article is now part of my book Node.js Progression. In jscomplete.com/node-beyond… Read an updated version of this content and more information about Node.js in.

At this year’s Forward. Js conference (a conference about JavaScript), I shared a talk titled “NodeJS You Don’t Know”. During that talk, I asked the audience a series of questions about the Nodejs runtime, most of which the technically literate audience couldn’t answer.

I don’t really count it but you can feel it in the boardroom. Some courageous people came up to me after the speech and admitted the truth.

That’s what brought me to speak. I don’t think we’re teaching Node.js the right way! Most of the learning about Node.js has focused on the Node package, not its runtime. Most Node packages encapsulate modules in their own Node runtime (such as HTTP or STREAM). When you run into problems, they may occur at runtime itself, and if you don’t understand the Node runtime, you’ll run into trouble.

Most of the learning about Node.js has focused on the Node package, not its runtime.

I selected some questions and answers for this article. In the following headings, try answering them first. (If you find any errors or ambiguous answers here, please let me know)

Question #1: What is a call stack? Is it part of V8?

Calls are definitely part of V8. It is a data structure used by V8 to hold the trace of a function call. Every time we run a function, V8 puts a reference to that function on the call stack and does the same for other functions nested within that function. This also includes recursively called functions.

Why is this important for Node? Because each Node process only gets one call stack. If you keep the call stack busy, the entire Node process is busy. Keep that in mind.

Question #2: What is event polling? Is it part of V8?

Where do you think the event polling is in the figure below?

libuv

Event polling is a mechanism for handling external events and converting them to run by callback functions. This kind of polling circularly selects events from the event queue and pushes their callback functions onto the call stack.

If this is the first time you’ve heard of an event loop, these definitions won’t help much. Event loops are just part of a larger framework:

Node.js

Node.jsAPIs is a function like setTimeout or fs.readfile. These are functions provided by Node.js that are not part of JavaScript.

The event loop is in the middle of this photo (actually a more complex version of it) and acts like an organizer. When the V8 call stack is empty, the event loop can decide what to do next.

Problem #3: When both the call stack and the event polling queue are empty,Node.jsWhat can you do?

It simply exits.

When you start a Node.js process, Node automatically starts event polling. When event polling is idle and there are no other events to process, the program exits.

To keep a Node process running, you need to place something somewhere in event queues. For example, when you start a timer or an HTTP server you are basically telling the event loop to keep running and checking on these events. To keep the Node process running, you need to put something into the event queue. For example, when you can start a timer or an HTTP service, you are telling event polling to keep running while listening for some events.

Question #4: Besides V8 and Libuv, what other external dependencies does Node have?

Here are all the independent libraries a Node process can use:

  • http-parser
  • c-ares
  • OpenSSL
  • Zlib they are all independent of Node, and they have their own source code and certificates. Node just uses them. So you need to keep that in mind if you want to know where your program is running. If you’re dealing with data compression, you might find yourself in azlibThe library bottom stack runs into trouble, then you are faced with onezilbErrors associated with Node rather than being blamed on Node.

Question #5: Can Node run without V8?

This can be a tricky one. You do need a VM to run the Node process, but V8 is not the only VM you can use. You can use Chakra.

Question # 6:module.exportsandexportsWhat’s the difference?

You can always export modules’ apis using module.exports. You can also use export in all but one case:

module.exports.g = ...  // Ok

exports.g = ...         // Ok

module.exports = ...    // Ok

exports = ...           // Not Ok
Copy the code

Why is that?

Export is simply an alias or reference to module.export. When you change an export, you change the reference without changing the official API (module.exports). You just need to get local variables in the module scope.

Question #7: Why are top-level variables not global variables?

If you define a top-level variable g in module1:

// module1.js

var g = 42;
Copy the code

And you have a module module2 that references module module1, and you try to access the variable G, and you’ll get G is not defined. The error.

Why is that?

If you do the same thing on the browser side, you can access the top-level variable in any script after the one that defines it. Each Node file has its own IIFE (function call expression) behind the scenes. All variables declared in the Node file apply to the IIFE.

Related question: What is the output of a Node file containing only one line of code?

// script.js

console.log(arguments);
Copy the code

You will see some parameters!

Why is that?

Because Node executes a function. Node wraps your code in a function. The five parameters you see above are clearly defined in this function.

Problem #8: These objects:export,require,moduleBoth are globally available, yet they vary from file to file. Why?

When you need to use the require object, you use it directly as a global variable. However, if you check require in two different files, you will see two different objects. Why is that? Because of the same IIFE magic:

As you can see, “this IIFE magic” passes the following five arguments to your code: exports, require, Module, __filename, and __dirname. When you use these five arguments in Node, they look like global variables, but they are really just function arguments.

Question #9: What are loop dependencies in Node?

If you define a module module1 that refers to module module2, and a module2 inside that refers to module module1. What will happen? An error?

// module1
require('./module2');

// module2
require('./module1');
Copy the code

You won’t get an error. Because Node allows that. Therefore, module Module1 references module Module2, but module Module2 depends on module Module1 and module Module1 has not been loaded, so module Module1 will only obtain a partial version of module Module2. The program will prompt a warning.

Question #10: When is it appropriate to use file system synchronization methods (e.g.readFileSync)?

Each method in the Node module FS has a synchronized version. Why would you use a synchronous method instead of an asynchronous method?

Sometimes it’s better to use a synchronous approach. You can use it in any initialization step, for example, while the server is still loading. Typically, everything that happens after the initialization step depends on the data that was retrieved there. As long as your use of synchronous methods is one-time, you can use synchronous methods to avoid introducing callback prisons.

However, if you use a synchronous method in a handler (such as an HTTP server request callback), it is simply 100% wrong. Don’t do that.

I hope you can answer some or all of these questions.

Thanks for reading.