Home  >  Article  >  Web Front-end  >  Nodejs study notes Global Objects global object_node.js

Nodejs study notes Global Objects global object_node.js

WBOY
WBOYOriginal
2016-05-16 16:20:441062browse

1, opening analysis

In the last chapter, we learned the basic theoretical knowledge of NodeJS. It is crucial to understand these theoretical knowledge. In the subsequent chapters, we will gradually learn the various modules in it according to the official documents. Okay, it’s time for the protagonist of this article to take the stage, Global

Let’s take a look at the official definition:

Global ObjectsGlobal ObjectsThese 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 are 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.

I think everyone should be familiar with the concept of global objects. In the browser, the highest level scope is Global Scope, which means that if you use "var" to define a variable in Global Scope, this variable will Will be defined as Global Scope.

But it is different in NodeJS. The highest level Scope is not Global Scope. Use "var" to define a variable in a Module. This variable is only in the Scope of this Module.

In NodeJS, variables, functions or methods defined in a module are only available within that module, but they can be passed outside the module through the use of the exports object.

However, in Node.js, there is still a global scope, that is, you can define some variables, functions or classes that can be used without loading any modules.

At the same time, some global methods and global classes are also predefined. The Global object is the global namespace in NodeJS. Any global variable, function or object is an attribute value of the object.

In the REPL running environment, you can observe the details in the Global object through the following statement, as shown in the figure below:

I will talk about the related attribute value objects mounted on the Global object one by one below.

(1), Process

Process {Object} The process object.See the process object section.

Process {object} This is a process object. I will go into detail in subsequent chapters, but here I want to take out an API to talk about it.

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 callback function in the next iteration of the event loop. This is not a simple alias for the setTimeout(fn, 0) function, as it is much more efficient.

This function can call our callback function before any I/O. This function is very important to you if you want to perform some operations after the object is created but before the I/O operation occurs.

There are many people who don’t 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, during its event polling process, only one event will be processed at the same time. You can think of event polling as a large queue. At each point in time, the system will only process one event.

Even if your computer has multiple CPU cores, you cannot process multiple events in parallel at the same time. But it is this characteristic that makes node.js suitable for processing I/O-type applications, but not suitable for CPU-based computing applications.

In every I/O type application, you only need to define a callback function for each input and output, and they will automatically be added to the event polling processing queue.

When the I/O operation is completed, this callback function will be triggered. The system will then continue processing other requests.

 

In this processing mode, process.nextTick() means to define an action and let this action be executed at the next event polling time point. Let's look at an example. There is a foo() in the example. If you want to call it at the next point in time, you can do this:

Copy code The code is as follows:

function foo() {
​ console.error('foo');
}

process.nextTick(foo);
console.error('bar');

Run the above code, and you will see from the information printed in the terminal below that the output of "bar" is in front of "foo". This verifies the above statement, foo() is run at the next point in time.

Copy code The code is as follows:

bar
foo

You can also use the setTimeout() function to achieve seemingly the same execution effect:

Copy code The code is as follows:

setTimeout(foo, 0);
console.log('bar');

But in terms of internal processing mechanism, process.nextTick() and setTimeout(fn, 0) are different. process.nextTick() is not a simple delay, it has more features .

To be more precise, the call defined by process.nextTick() creates a new substack. You can perform any number of operations on the current stack. But once netxTick is called, the function must return to the parent stack. Then the event polling mechanism waits for new events to be processed again. If a call to nextTick is found, a new stack will be created.

Let’s take a look at when to use process.nextTick():

Cross-execute CPU-intensive tasks across multiple events:

In the following example, there is a compute(). We hope that this function will be executed as continuously as possible to perform some computationally 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 and handle other events. This application model is like a single-threaded web service server. Here we can use process.nextTick() to cross-execute compute() and normal event response.

Copy code 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, '127.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() to be executed at the next point in time.

During this process, if a new http request comes in, the event loop mechanism will first process the new request and then call compute().

On the contrary, if you put compute() in a recursive call, the system will always be blocked in compute() and cannot handle new http requests. You can try it yourself.

Of course, we cannot obtain the real benefits of parallel execution under multiple CPUs through process.nextTick(). This only simulates the segmented execution of the same application on the CPU.

 (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 test below:

 

Copy code The code is as follows:

console.log("Hello Bigbear!") ;
for(var i in console){
console.log(i " " console[i]) ;
}

You will get the following output:

Copy code 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('util');
  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: NaNms', 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 = 'Trace';
  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));
  }
}

  通过这些函数,我们基本上知道NodeJS在全局作用域添加了些什么内容,其实Console对象上的相关api只是对Process对象上的"stdout.write“进行了更高级的封装挂在到了全局对象上。

 (3),exports与module.exports

   在NodeJS中,有两种作用域,分为全局作用域和模块作用域  

复制代码 代码如下:

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);

  我们看到var name = 'var-name';name = 'name'; 是定义的局部变量;

  而global.name='global-name';是为 全局对象定义一个name 属性,

  而 this.name = 'module-name';是为模块对象定义了一个name 属性

  那么我们来验证一下,将下面保存成test2.js,运行

复制代码 代码如下:

var t1 = require('./test1'); 
console.log(t1.name); 
console.log(global.name);

  从结果可以看出,我们成功导入 了test1 模块,并运行了 test1的代码,因为在test2 中 输出 了global.name,

  而 t1.name 则是 test1 模块中通过this.name 定义的,说明this 指向 的是 模块作用域对象。

  exports与module.exports的一点区别

    Module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是Module.exports而不是exports。

    所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是Module.exports本身不具备任何属性和方法

    如果,Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。

  举个栗子:

    新建一个文件 bb.js

复制代码 代码如下:

exports.name = function() {
    console.log('My name is 大熊 !') ;
} ;

    创建一个测试文件 test.js

  

复制代码 代码如下:

var bb= require('./bb.js');
bb.name(); // 'My name is 大熊 !'

    修改bb.js如下:

复制代码 代码如下:

module.exports = 'BigBear!' ;
exports.name = function() {
console.log('My name is Big Bear!') ;
} ;

Reference and execute bb.js again

Copy code The code is as follows:

var bb= require('./bb.js');
bb.name(); // has no method 'name'

It can be seen that your module does not necessarily have to return an "instantiated object". Your module can be any legal JavaScript object - boolean, number, date, JSON, string, function, array, etc.

(4), setTimeout, setInterval, process.nextTick, setImmediate

The following appears in the form of summary

Nodejs is characterized by event-driven, high concurrency generated by asynchronous I/O. The engine that produces this feature is the event loop. Events are classified into corresponding event observers, such as idle observers and timer observers. , I/O observers, etc. Each cycle of the event loop is called a Tick. Each Tick takes out events from the event observer in order and processes them.

The timer created when calling setTimeout() or setInterval() will be placed in the red-black tree inside the timer observer. Every time it ticks, it will check whether the timer has exceeded the timeout from the red-black tree. , if it exceeds, the corresponding callback function will be executed immediately. Both setTimeout() and setInterval() are used as timers. The difference between them is that the latter is triggered repeatedly, and because the time is set too short, the processing after the previous trigger will be triggered immediately after the processing is completed.

Since the timer is triggered by timeout, this will lead to reduced triggering accuracy. For example, the timeout set with setTimeout is 5 seconds. When the event loop loops through a task at the 4th second and its execution time is 3 seconds, Then the setTimeout callback function will expire in 2 seconds, which is the reason for the reduced accuracy. And because the red-black tree and iteration methods are used to save timers and determine triggers, it is a waste of performance.

All callback functions set using process.nextTick() will be placed in the array, and all will be executed immediately on the next Tick. This operation is relatively lightweight and has high time accuracy.

The callback function set by setImmediate() is also called on the next Tick. The difference between it and process.nextTick() lies in two points:

 1. The observers they belong to are executed with different priorities. process.nextTick() belongs to the idle observer, setImmediate() belongs to the check observer, and the priority of 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.

Second, summarize

1. Understand the meaning of the existence of Global objects

2. A little difference between exports and module.exports

3. What is the underlying structure of Console (high-level encapsulation of Process object)

4. The difference between setTimeout, setInterval, process.nextTick, and setImmediate

5. Two types of scopes in NodeJS

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn