This is the second article in The NodeJS Study Notes series. From this article, we will learn about each node. js module one by one based on the official documents. First, we will learn about Global
I. Opening Analysis
In the previous chapter, we learned the basic theoretical knowledge of NodeJS. understanding of these theoretical knowledge is crucial. In the subsequent chapters, we will gradually learn from the various modules in the official documents. Well, it's time for the main character of this article to go on stage, Global
Let's take a look at the official definition:
Global Objects global Object These objects are available in all modules. Some of these objects aren't actually in the Global scope but in the module scope-this will be noted.
These objects are available in all modules. In fact, some objects are not in the global scope, but in its module scope ------ these will be identified.
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scopevar somethingWill define a global variable.
In Node this is different. The top-level scope is not the global scope;var somethingInside a Node module will be local to that module.
The Global Object concept should not be unfamiliar to everyone. In a browser, the highest level of Scope is Global Scope, which means that if you use "var" to define a variable in Global Scope, this variable will be defined as Global Scope.
But it is different in NodeJS. The highest level Scope is not Global Scope. In a Module, use "var" to define a variable. This variable is only in the Scope of this Module.
In NodeJS, variables, functions, or methods defined in a module are only available in this module, but can be passed to the external module through the use of the exports object.
However, in Node. js, there is still a global scope, that is, you can define variables, functions, or classes that can be used without loading any modules.
At the same time, some pre-defined Global methods and Global class Global objects are the Global namespaces in NodeJS. Any Global variables, functions, or objects are attribute values of this object.
In the REPL running environment, you can use the following statement to observe the details of the Global object. For details, see:
Next I will talk about the property value objects attached to Global objects one by one.
(1), Process
Process {Object} The process object. See the process object section.
Process {object} is a process object. I will elaborate in the subsequent chapters, but here I will first come up with an api.
Process. nextTick (callback)
On the next loop around the event loop call this callback. this is not a simple alias to setTimeout (fn, 0), it's much more efficient. it typically runs before any other I/O events fire, but there are some exceptions. see process. maxTickDepth below.
Call the callback function in the next cycle of the event loop. This is not a simple alias for the setTimeout (fn, 0) function, because it is much more efficient.
This function can call our callback function before any I/O operation. If you want to perform some operations after the object is created and before the I/O operation occurs, this function is very important to you.
Many people do not understand the usage of process. nextTick () in Node. js. Let's take a look at what process. nextTick () is and how to use it.
Node. js is single-threaded. In addition to system IO, only one event can be processed at a time during event polling. You can think of event polling as a large queue. At each point in time, the system only processes one event.
Even if your computer has multiple CPU cores, you cannot process multiple events concurrently. However, this feature makes node. js suitable for processing I/O-type applications and not suitable for CPU computing applications.
In each I/O application, you only need to define a callback function for each input and output, and they will be automatically added to the event polling processing queue.
After the I/O operation is complete, this callback function is triggered. The system then continues to process other requests.
In this processing mode, process. nextTick () means to define an action and execute it at the time point of the next event polling. Let's look at an example. In this example, there is a foo (). If you want to call it at the next time point, you can do this:
The Code is as follows:
Function foo (){
Console. error ('foo ');
}
Process. nextTick (foo );
Console. error ('bar ');
Run the code above. You can see from the information printed on the terminal below that the output of bar is in front of foo. This proves that foo () runs at the next time point.
The Code is as follows:
Bar
Foo
You can also use the setTimeout () function to achieve the same execution effect:
The Code is as follows:
SetTimeout (foo, 0 );
Console. log ('bar ');
However, in the internal processing mechanism, process. nextTick () and setTimeout (fn, 0) are different. process. nextTick () is not a simple latency, but has more features.
More accurately, a new sub-stack is created for calls defined by process. nextTick. In the current stack, you can perform any number of operations. However, once netxTick is called, the function must return to the parent stack. Then, the event polling mechanism waits again to process new events. If nextTick is called, a new stack is created.
Next let's take a look at the situation where process. nextTick () is used ():
Cross-execution of CPU-intensive tasks in multiple events:
In the following example, there is a compute (). We hope this function can be executed as continuously as possible to perform some computation intensive tasks.
But at the same time, we also hope that the system will not be blocked by this function, but also need to be able to respond to other events. This application mode is like a single-threaded web service server. Here we can use process. nextTick () to cross-Execute compute () and normal event response.
The Code is as follows:
Var http = require ('http ');
Function compute (){
// Performs complicated calculations continuously
//...
Process. nextTick (compute );
}
Http. createServer (function (req, res ){
Res. writeHead (200, {'content-type': 'text/plain '});
Res. end ('Hello World ');
}). Listen (5000, '192. 0.0.1 ');
Compute ();
In this mode, we do not need to call compute () recursively. We only need to use process. nextTick () in the event loop to define compute () for execution at the next time point.
In this process, if a new http request comes in, the event Loop Mechanism will first process the new request and then call compute ().
If you put compute () in a recursive call, the system will be congested in compute () and cannot process new http requests. You can try it on your own.
Of course, we cannot use process. nextTick () to achieve the real benefit of parallel execution under multiple CPUs. This is just to simulate the same application to be executed on the CPU in segments.
(2), Console
Console {Object} Used to print to stdout and stderr. See the stdio section.
Console {object} is used to print to standard output and error output. See the following test:
The Code is as follows:
Console. log ("Hello Bigbear! ");
For (var I in console ){
Console. log (I + "" + console [I]);
}
The following output result is displayed:
The Code is as follows:
Var log = function (){
Process. stdout. write (format. apply (this, arguments) + '\ n ');
}
Var info = function (){
Process. stdout. write (format. apply (this, arguments) + '\ n ');
}
Var warn = function (){
WriteError (format. apply (this, arguments) + '\ n ');
}
Var error = function (){
WriteError (format. apply (this, arguments) + '\ n ');
}
Var dir = function (object ){
Var util = require ('til ');
Process. stdout. write (util. inspect (object) + '\ n ');
}
Var time = function (label ){
Times [label] = Date. now ();
}
Var timeEnd = function (label ){
Var duration = Date. now ()-times [label];
Exports. log ('undefined: nanm', label, duration );
}
Var trace = function (label ){
// TODO probably can to do this better with V8's debug object once that is
// Exposed.
Var err = new Error;
Err. name = 'track ';
Err. message = label | '';
Error. captureStackTrace (err, arguments. callee );
Console. error (err. stack );
}
Var assert = function (expression ){
If (! Expression ){
Var arr = Array. prototype. slice. call (arguments, 1 );
Require ('assert '). OK (false, format. apply (this, arr ));
}
}
Through these functions, we basically know what NodeJS has added to the global scope. In fact, the related APIs on the Console object are only "stdout. write "is encapsulated in a more advanced way and mounted to the global object.
(3), exports and module. exports
NodeJS has two scopes: global scope and module scope.
The Code is as follows:
Var name = 'var-name ';
Name = 'name ';
Global. name = 'Global-name ';
This. name = 'module-name ';
Console. log (global. name );
Console. log (this. name );
Console. log (name );
We can see that var name = 'var-name'; name = 'name'; is the defined local variable;
Global. name = 'Global-name'; defines a name attribute for the global object,
This. name = 'module-name'; defines a name attribute for the module object.
Then let's verify it, save the following as test2.js, and run
The Code is as follows:
Var t1 = require ('./test1 ');
Console. log (t1.name );
Console. log (global. name );
We can see from the results that we have successfully imported the test1 module and run the test1 code, because the global. name,
T1.name is defined in the test1 module through this. name, indicating that this points to the module scope object.
Differences between exports and module. exports
Module.exportsIs the real interface, exports is just a helper tool. Which of the following statements is returned to the call?Module.exportsInstead of exports.
All the properties and Methods Collected by exports are assignedModule.exports. Of course, there is a premise thatModule.exportsIt does not have any attributes or methods.。
If,Module.exportsSome attributes and methods are available, so the information collected by exports will be ignored.
Example:
Create a file bb. js
The Code is as follows:
Exports. name = function (){
Console. log ('My name is big bear! ');
};
Create a test file test. js
The Code is as follows:
Var bb = require ('./bb. js ');
Bb. name (); // 'My name is a big bear! '
Modify bb. js as follows:
The Code is as follows:
Module. exports = 'bigbear! ';
Exports. name = function (){
Console. log ('My name is big bear! ');
};
Reference again and execute bb. js
The Code is as follows:
Var bb = require ('./bb. js ');
Bb. name (); // has no method 'name'
We can see that your module does not have to return an "instantiated object ". Your module can be any legal javascript Object-boolean, number, date, JSON, string, function, array, and so on.
(4), setTimeout, setInterval, process. nextTick, setImmediate
The following is a summary
Nodejs features event-driven, high concurrency produced by asynchronous I/O. the engine that generates this feature is an event loop, and events are classified into corresponding event observers, for example, the idle observer, the timer observer, and the I/O observer. Each cycle of an event is called a Tick. Each Tick extracts the event from the event observer for processing in sequence.
The timer created when setTimeout () or setInterval () is called will be placed in the red/black tree inside the timer observer. Each time Tick is used, the timer will be checked from the red/black tree to check whether the timer has exceeded the scheduled time, if this parameter is exceeded, the corresponding callback function is executed immediately. Both setTimeout () and setInterval () are used when the timer is used. The difference is that the latter is triggered repeatedly, and because the time is too short, the processing after the previous trigger will be triggered immediately after the processing is completed.
Because the timer is triggered by time-out, this will reduce the trigger precision. For example, if the time-out time set by setTimeout is 5 seconds, when the event loop is a task in 4th seconds, if the execution time is 3 seconds, the setTimeout callback function will expire for 2 seconds, which is the cause of reduced precision. In addition, the use of the Red/black tree and iterative method to save the timer and determine the trigger is a waste of performance.
All the callback functions set using process. nextTick () will be placed in the array, and all the callback functions will be executed immediately in the next Tick operation. This operation is lightweight and has a high time precision.
The callback function set by setImmediate () is also called at the next Tick. The difference between the callback function and process. nextTick () is as follows:
1. The priorities of the observer to which they belong are different. process. nextTick () belongs to the idle observer, setImmediate () belongs to the check observer, and idle> check.
2. The callback function set by setImmediate () is placed in a linked list. Each Tick only executes One callback in the linked list. This is to ensure that each Tick can be executed quickly.
Ii. Summary
1. Understand the meaning of Global Objects
2. Differences between exports and module. exports
3. What is the underlying layer of the Console (high-level encapsulation of the Process object)
4, setTimeout, setInterval, process. nextTick, setImmediate
5. Two scopes in NodeJS