Node.js summary

Time:2021-4-8

Node.js summary

1. Introduction

Node is the server running environment of JavaScript language.

The so-called “running environment” has two meanings: first, JavaScript language runs on the server through node. In this sense, node is a bit like a JavaScript virtual machine; second, node provides a large number of tool libraries to enable JavaScript language to interact with the operating system (such as reading and writing files and creating new subprocesses). In this sense, node is also a tool library for JavaScript.

Node uses Google’s V8 engine as JavaScript interpreter, and calls operating system resources through self-developed libuv library.

1.1 installation and update

Visit the official websitenodejs.orgperhapsgithub.com/nodesource/distributionsTo view the latest version and installation method of node.

The official website provides compiled binary packages, which can be decompressed to/usr/localUnder the table of contents.

$ tar -xf node-someversion.tgz

Then, create symbolic links and add them to the path in the $path variable.

$ ln -s /usr/local/node/bin/node /usr/local/bin/node
$ ln -s /usr/local/node/bin/npm /usr/local/bin/npm

Here is how to install DEB package in Ubuntu and Debian.

$ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
$ sudo apt-get install -y nodejs

$ apt-get install nodejs

After the installation is completed, run the following command to see if it works properly.

$ node --version
#Or
$ node -v

to update node.js Version, which can be accessed through node.js OfnThe module is completed.

$ sudo npm install n -g
$ sudo n stable

The above code passednModule, will node.js Update to the latest released stable version.

nThe module can also specify to install a specific version of node.

$ sudo n 0.10.21

1.2 version management tool NVM

If you want to install multiple versions of the node.js You need to use the version management tool NVM.

$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh

After installation, the execution script of NVM should be activated before each use. It is recommended to add it to ~ /. Bashrc file (assuming Bash is used). After activation, you can install the specified version of node.

#Install the latest version
$ nvm install node

#Install the specified version
$ nvm install 0.12.1

#Use the latest version installed
$ nvm use node

#Use the specified version of node
$ nvm use 0.12

NVM is also allowed to enter the specified version of the repl environment.

$ nvm run 0.12

If you create a new. Nvmrc file in the root directory of the project and write the version number to it, you can only enternvm useCommand, there is no need to attach the version number.

Here are other commands that are often used.

#View all locally installed versions
$ nvm ls

#View all versions available for installation on the server.
$ nvm ls-remote

#Exit the active NVM and use the activate command.
$ nvm deactivate

1.3 basic usage

After the installation, run the node.js Program is to use the node command to read JavaScript scripts.

Current directorydemo.jsScript file, which can be executed in this way.

$ node demo
#Or
$ node demo.js

use-eParameter to execute the code string.

$ node -e 'console.log("Hello World")'
Hello World

1.4 repl environment

Type the node command on the command line, and enter a Node.js In the repl environment (read – Eval – print loop, “read evaluate output” loop), you can directly run various JavaScript commands.

$ node
> 1+1
2
>

If the parameter – use is used_ Strict, repl will run in strict mode.

$ node --use_strict

Repl is Node.js Shell interaction with users, a variety of basic shell functions can be used in it, such as using the up and down arrow keys to traverse the used commands.

Special variable underline (?) Represents the return result of the previous command.

> 1 + 1
2
> _ + 1
3

In repl, if you run an expression, the result is returned directly on the command line. If you run a statement, there is no output because the statement does not return a value.

> x = 1
1
> var x = 1

The second command of the above code does not show any results. Because this is a statement, not an expression, there is no return value.

1.5 asynchronous operation

Node uses V8 engine to process JavaScript scripts, and its biggest feature is single thread running, which can only run one task at a time. This causes node to adopt asynchronous operation, that is, the task is not executed immediately, but inserted at the end of the task queue and executed after the previous task is finished.

Because of this feature, the subsequent operation of a task is often defined in the form of callback function.

var isTrue = function(value, callback) {
  if (value === true) {
    callback(null, "Value was true.");
  }
  else {
    callback(new Error("Value is not true!"));
  }
}

The above code gives further processing to the callback function callback.

Node convention, if a function needs a callback function as a parameter, then the callback function is the last parameter. In addition, the first parameter of the callback function itself is the error object passed in the previous step.

var callback = function (error, value) {
  if (error) {
    return console.log(error);
  }
  console.log(value);
}

In the above code, the first parameter of callback is the error object, and the second parameter is the real data parameter. This is because the callback function is mainly used for asynchronous operation. When the callback function is running, the previous operation ends early, and the error execution stack no longer exists Catch doesn’t work for asynchronous operations, so you have to leave the error to the callback function.

try {
  db.User.get(userId, function(err, user) {
    if(err) {
      throw err
    }
    // ...
  })
} catch(e) {
  console.log(‘Oh no!’);
}

In the code above, db.User.get Method is an asynchronous operation. When an error is thrown, it may be in the try The catch code block has been running for a long time, which results in the error not being caught. Therefore, node uniformly stipulates that once an error occurs in an asynchronous operation, the error object will be passed to the callback function.

If no error occurs, null is passed in the first parameter of the callback function. This writing method has a great advantage, that is, as long as you judge the first parameter of the callback function, you will know whether there is an error. If it is not null, there must be an error. In addition, you can pass errors layer by layer.

if(err) {
  //Except for the no permission error, other errors are passed to the next callback function
  if(!err.noPermission) {
    return next(err);
  }
}

1.6 global objects and global variables

Node provides the following global objects that all modules can call.

  • Global: represents the global environment of node, similar to the window object of browser. It should be noted that if you declare a global variable in the browser, you actually declare the properties of a global object, such asvar x = 1Equivalent to settingswindow.x = 1But node is not, at least not in the module (the behavior of the repl environment is the same as that of the browser). In the module file, declarevar x = 1, which is notglobalObject,global.xIt’s equivalent to undefined. This is because the global variables of the module are private to the module, and other modules cannot get them.

  • Process: this object represents the current process of node, allowing developers to interact with this process.

  • Console: points to the built-in console module of node, and provides standard input and output functions in the command line environment.

Node also provides some global functions.

  • Settimeout(): used to run the callback function after the specified milliseconds. The actual call interval also depends on system factors. The number of milliseconds in the interval is between 1 ms and 2147483647 MS (about 24.8 days). If it exceeds this range, it will be automatically changed to 1 millisecond. This method returns an integer representing the number of the new timer.
  • Cleartimeout(): used to terminate a timer created by the setTimeout method.
  • Setinterval(): used to call the callback function every certain millisecond. Due to system factors, it may not be possible to guarantee that the interval between each call is exactly the specified number of milliseconds, but it will only be more than this interval, not less than it. The specified number of milliseconds must be an integer between 1 and 2147483647 (about 24.8 days). If it exceeds this range, it will be automatically changed to 1 millisecond. This method returns an integer representing the number of the new timer.
  • Clearinterval(): terminate a timer created by setinterval method.
  • Require (): used to load modules.
  • Buffer (): used to manipulate binary data.

Node provides two global variables, both starting with two underscores.

  • __filename: points to the file name of the currently running script.
  • __dirname: points to the directory where the currently running script is located.

In addition, there are some objects that are actually local variables within the module, pointing to different objects according to different modules. However, all modules are applicable and can be regarded as pseudo global variables, mainly modules, module.exports , exports, etc.

2. Modular structure

2.1 overview

Node.js The modular structure is adopted, according to theCommonjs specificationDefine and use modules. Module and file are one-to-one correspondence, that is, loading a module is actually loading a corresponding module file.

The require command is used to specify the loading module, and the suffix of the script file can be omitted when loading.

var circle = require('./circle.js');
//Or
var circle = require('./circle');

The parameter of the require method is the name of the module file. It can be divided into two cases. The first case is that the parameter contains a file path (for example, the above example). In this case, the path is relative to the directory where the current script is located. The second case is that the parameter does not contain a file path. In this case, node goes to the installation directory of the module to find the installed module (for example, the following example).

var bar = require('bar');

Sometimes, a module itself is a directory that contains multiple files. At this time, node package.json File, find the module entry file specified by the main attribute.

{
  "name" : "bar",
  "main" : "./lib/bar.js"
}

In the above code, the startup file of the module is in the Lib subdirectory bar.js . When usingrequire('bar')When the command loads the module, it actually loads the./node_modules/bar/lib/bar.jsDocuments. The following will have the same effect.

var bar = require('bar/lib/bar.js')

If not in the module directory package.json Documents, node.js Will try to find in the module directory index.js or index.node File to load.

Once the module is loaded, it will be cached by the system. If the module is loaded a second time, the version in the cache is returned, which means that the module is actually executed only once. If you want the module to execute multiple times, you can have the module return a function and then call it multiple times.

2.2 core module

If you just run JavaScript code on the server, it’s not very useful, because there are many kinds of server scripting languages. Node.js It also provides a series of functional modules to interact with the operating system. These core function modules can be used without installation. Here is a list of them.

  • Http: provides HTTP server function.
  • URL: resolve the URL.
  • FS: interact with the file system.
  • Querystring: parses the URL of the query string.
  • child_ Process: create a new child process.
  • Util: provides a series of utility tools.
  • Path: processing file path.
  • Crypto: provides encryption and decryption functions, which is basically the packaging of OpenSSL.

The source code of the above core modules is in the Lib subdirectory of node. In order to improve the running speed, they will be compiled into binary files when they are installed.

Core modules are always loaded first. If you write an HTTP module yourself,require('http')The core module is loaded.

2.3 custom module

The node module adopts the common JS specification. As long as this specification is met, you can customize the module.

The following is the simplest module. Suppose you create a new one foo.js File, write the following.

// foo.js

module.exports = function(x) {
    console.log(x);
};

The above code is a module, and it passes through the module.exports Variable, output a method.

The usage of this module is as follows.

// index.js

var m = require('./foo');

M ("this is a custom module");

The above code loads the module file through the require command foo.js (suffix name omitted), export the module’s external interface to variable m, and then call m. At this point, run it from the command line index.js “This is a custom module” will be printed on the screen.

$ node index
This is a custom module

Module variable is the top variable of the whole module file, and its exports attribute is the interface of module output. If you directly output a function (as shown above) foo.js )To call a module is to call a function. However, a module can also output an object. Here’s how foo.js Rewrite it.

// foo.js

var out = new Object();

function p(string) {
  console.log(string);
}

out.print = p;

module.exports = out;

The above code represents the module output out object, which has a print attribute pointing to a function. Here is how to use this module.

// index.js

var m = require('./foo');

m. Print ("this is a custom module");

The above code indicates that since the specific method is defined on the print attribute of the module, the print attribute must be explicitly called.

3. Exception handling

Node is a single thread running environment. Once the exception thrown is not caught, the whole process will crash. Therefore, the node exception handling is very important to ensure the stable operation of the system.

Generally speaking, node has three ways to propagate an error.

  • Use the throw statement to throw an error object, that is, an exception.
  • The error object is passed to the callback function, which is responsible for issuing the error.
  • Issue an error event through the EventEmitter interface.

3.1 try… Catch structure

The most common way to catch exceptions is to use try Catch structure. However, this structure cannot catch exceptions thrown by code that runs asynchronously.

try {
  process.nextTick(function () {
    throw new Error("error");
  });
} catch (err) {
  //can not catch it
  console.log(err);
}

try {
  setTimeout(function(){
    throw new Error("error");
  },1)
} catch (err) {
  //can not catch it
  console.log(err);
}

The above codes are process.nextTick And setTimeout method, throw two exceptions in the next round of event loop, representing the error thrown by asynchronous operation. None of them can be captured by the catch code block because the part where the catch code block is located has finished running.

One solution is to put error capture code into asynchronous execution as well.

function async(cb, err) {
  setTimeout(function() {
    try {
      if (true)
        throw new Error("woops!");
      else
        cb("done");
    } catch(e) {
      err(e);
    }
  }, 2000)
}

async(function(res) {
  console.log("received:", res);
}, function(err) {
  console.log("Error: async threw an exception:", err);
});
// Error: async threw an exception: Error: woops!

In the above code, the async function can also be deployed in the asynchronous catch code block.

These two methods are not ideal. Generally speaking, node only uses try / catch statement in a few occasions, such as usingJSON.parseParse the JSON text.

3.2 callback function

Node takes the error object as the first parameter and passes it into the callback function. This avoids the problem that the capture code is not in the same time period as the error code.

fs.readFile('/foo.txt', function(err, data) {
  if (err !== null) throw err;
  console.log(data);
});

The above code indicates that reading the filefoo.txtIs an asynchronous operation, its callback function has two parameters, the first is the error object, the second is the read file data. If the first parameter is not null, it means that an error has occurred, and the following code will no longer be executed.

Here is a complete example.

function async2(continuation) {
  setTimeout(function() {
    try {
      var res = 42;
      if (true)
        throw new Error("woops!");
      else
        continuation(null, res); // pass 'null' for error
    } catch(e) {
      continuation(e, null);
    }
  }, 2000);
}

async2(function(err, res) {
  if (err)
    console.log("Error: (cps) failed:", err);
  else
    console.log("(cps) received:", res);
});
// Error: (cps) failed: woops!

In the above code, the first parameter of the callback function of async2 function is an error object, which is to handle the error thrown by asynchronous operation.

3.3 error event of EventEmitter interface

When an error occurs, you can also use the EventEmitter interface to throw an error event.

var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

emitter.emit('error', new Error('something bad happened'));

You must be careful when using the above code, because if you do not deploy a listening function for the error event, the entire application will crash. Therefore, it is always necessary to deploy the following code at the same time.

emitter.on('error', function(err) {
  console.error ('error: '+ err.message );
});

3.4 uncaughtexception event

When an exception is not caught, the uncaughtexception event will be triggered. You can register a callback function for this event to catch the exception.

var logger = require('tracer').console();
process.on('uncaughtException', function(err) {
  console.error('Error caught in uncaughtException event:', err);
});

try {
  setTimeout(function(){
    throw new Error("error");
  },1);
} catch (err) {
  //can not catch it
  console.log(err);
}

As long as the callback is configured for uncaughtexception, the node process will not exit abnormally, but the context of the exception has been lost, and the details of the exception cannot be given. Moreover, the exception may cause the node not to recover the memory normally, resulting in memory leakage. Therefore, when uncaughtexception is triggered, it is better to record the error log, and then end the node process.

process.on('uncaughtException', function(err) {
  logger.log(err);
  process.exit(1);
});

3.5 unhandledrejection event

Iojs has an unhandledrejection event, which is used to listen for the rejected state of a project object that is not captured.

var promise = new Promise(function(resolve, reject) {
  reject(new Error("Broken."));
});

promise.then(function(result) {
  console.log(result);
})

In the above code, the state of project changes to rejected and an error is thrown. However, there is no reaction because no handler is set.

This problem can be solved by listening to the unhandledrejection event.

process.on('unhandledRejection', function (err, p) {
  console.error(err.stack);
})

It should be noted that the listener function of the unhandledrejection event has two parameters: the first is the error object, and the second is the project object that generates the error. This can provide a lot of useful information.

var http = require('http');

http.createServer(function (req, res) {
  var promise = new Promise(function(resolve, reject) {
    reject(new Error("Broken."))
  })

  promise.info = {url: req.url}
}).listen(8080)

process.on('unhandledRejection', function (err, p) {
  if (p.info && p.info.url) {
    console.log('Error in URL', p.info.url)
  }
  console.error(err.stack)
})

The above code will output the URL requested by the user in case of error.

Error in URL /testurl
Error: Broken.
  at /Users/mikeal/tmp/test.js:9:14
  at Server. (/Users/mikeal/tmp/test.js:4:17)
  at emitTwo (events.js:87:13)
  at Server.emit (events.js:169:7)
  at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:471:12)
  at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23)
  at Socket.socketOnData (_http_server.js:322:22)
  at emitOne (events.js:77:13)
  at Socket.emit (events.js:166:7)
  at readableAddChunk (_stream_readable.js:145:16)

4. Command line script

The node script can be used as a command line script.

$ node foo.js

The above code is executed foo.js Script file.

foo.js The first line of the file, if the interpreter location is added, can be called directly as a command line tool.

#!/usr/bin/env node

You need to change the permissions of the file before calling.

$ chmod u+x foo.js
$ ./foo.js arg1 arg2 ...

As a command line script,console.logUsed to output content to standard output,process.stdinUsed to read standard input,child_process.exec()Used to execute a shell command.

5. Reference link

From: Ruan Yifenghttps://javascript.ruanyifeng.com/nodejs/basic.html#toc1