Dig into some of the features in node. js

  • 2020-03-30 03:58:49
  • OfStack

As an emerging backend language, node. js is designed to help programmers quickly build scalable applications. Node.js has many attractions and numerous reports about it. This article will analyze and discuss features such as EventEmitter, Streams, Coding Style, Linting, Coding Style, etc., to help users have a deeper understanding of node. js.

As a platform based on the Chrome JavaScript runtime, everything we know about JavaScript seems to apply to node applications. We can apply our front-end programming experience to back-end programming without additional language extensions or modifications.

EventEmitter

You should first understand the EventEmitter model. It can send an event and get consumers to subscribe to events of interest. We can think of it as an extension of the call-pass pattern to an asynchronous function. In particular, EventEmitter can be advantageous when multiple callbacks are required.

For example, a caller sends a "list files" request to a remote server. You may want to group the results returned, and each group is processed with a callback. The EventEmitter model lets you send "file" callbacks on each group to "end" when all is done.

When you use EventEmitter, you just set the events and parameters.


var EventEmitter = require('events').EventEmitter; 
var util = require('util'); 
 
function MyClass() { 
  if (!(this instanceof MyClass)) return new MyClass(); 
 
  EventEmitter.call(this); 
 
  var self = this; 
  setTimeout(function timeoutCb() { 
    self.emit('myEvent', 'hello world', 42); 
  }, 1000); 

util.inherits(MyClass, EventEmitter); 

The MyClass constructor creates a time trigger with a firing delay of 1s and a firing event of myEvent. To use related events, execute the on() method:


var myObj = new MyClass(); 
var start = Date.now(); 
myObj.on('myEvent', function myEventCb(str, num) { 
  console.log('myEvent triggered', str, num, Date.now() - start); 
}); 

Note here that while the subscribed EventEmitter event is asynchronous, the listener's actions are synchronous when the time is triggered. So if the above myEvent event has 10 listeners, all the listeners will be called in order without waiting for the loop of events.

If a subclass of EventEmitter generates a emit(' error') event, but no listeners subscribe to it, the EventEmitter base class throws an exception that causes uncaughtException to be triggered when the process object is executed.

verror

Verror is an extension of the base class Error that lets us define the output message using the printf character format.

Streams (flow)

If you have a very large file that needs to be processed, the ideal way is to read part of it, write part of it, no matter how big the file is, as long as time permits, it will always be processed. Streams is another widely used model in Node, where it is the implementation of EventEmitter. Provides readable, writable, or full-duplex interfaces. It is an abstract interface that provides regular operational events such as readable, writable, drain, data, end, and close. If we can use pipelines to effectively integrate these events, we can achieve more powerful interactions.

Using. Pipe (), the Note can communicate with back-pressure through the pipeline. Back-pressure means: read only those that can be written, or write only those that can be read.

For example, we now send data from stdin to a local file and a remote server:


var fs = require('fs');
var net = require('net'); var localFile = fs.createWriteStream('localFile.tmp'); net.connect('255.255.255.255', 12345, function(client) {
  process.stdin.pipe(client);
  process.stdin.pipe(localFile);
});

If we want to send data to a local file and want to compress the stream with gunzip, we can do this:


var fs = require('fs');
var zlib = require('zlib'); process.stdin.pipe(zlib.createGunzip()).pipe(fs.createWriteStream('localFile.tar'));

If you want to know more about the stream, please click (link: http://www.joyent.com/blog/streams-in-node).

Control Flow

Because JS has the first class of objects, closures, and other functional concepts, it is easy to define callback permissions. This is handy when prototyping, and enables integration of logical permissions as needed. But it is also prone to using clunky built-in functions.

For example, we want to read a series of files in order and then perform a task:


fs.readFile('firstFile', 'utf8', function firstCb(err, firstFile) {
  doSomething(firstFile);
  fs.readFile('secondFile', 'utf8', function secondCb(err, secondFile) {
    doSomething(secondFile);
    fs.readFile('thirdFile', 'utf8', function thirdCb(err, thirdFile) {
      doSomething(thirdFile);
    });
  });
});

The problem with this model is:

1. The logic of these codes is very disorderly and the relevant operation flow is difficult to understand.
2. No errors or exception handling.
3. Closure memory leaks in JS are very common and difficult to diagnose and detect.

If we want to do a series of asynchronous operations on an input set, it is more sensible to use a flow control library. Vasync is used here.

Vasync is a process control library whose idea is derived from asynchronous operations. What makes it special is that it allows consumers to view and observe a process. This information is very useful for studying how an error occurs.

Coding Style

Programming style is one of the most controversial topics because it is so often casual. Every man has his hobbyhorse. The important thing is to find the style that suits the individual and the team. Some heritage might make the Node development journey better.

1. Name the function
2. Try to name all functions.
3. Avoid closures
Don't define other functions in one function. This can reduce many unexpected closure memory leaks.
5. More and smaller functions

The V8 JIT is a powerful engine, but smaller and leaner functions will work better with V8. Furthermore, if our functions are small (around 100 lines), we'll thank ourselves for reading and maintaining them ourselves.

Programmatically check style: maintain style consistency and use a check tool to enforce it. We use jsstyle.

Linting(code review)

The Lint tool can perform static analysis of the code without running, checking for potential errors and risks, such as missing a break statement in caseswitch. Lint is not simply synonymous with style checking; it is more about objective risk analysis than subjective style selection. We use javascriptlint, which has a wealth of check items.

Logging

When we program and code, we need to take a long view. In particular, consider what tools to use for debugging. A great first step is effective logging. We need to identify the information to see what to look for when debugging and what to analyze at run time. Here recommended Bunyan, a direct Node. Js (link: https://www.joyent.com/developers/node/design#bunyan), and data output format is (link: http://www.joyent.com/blog/node-js-in-production-runtime-log-snooping), for more information, please click here.

The Client Server

If an application has distributed processing power, it will be more attractive in the market. Similar interfaces can be described using HTTP RESTFul apis or raw TCP JSON. This allows developers to combine the experience on Node with asynchronous network environments and the use of streams with distributed extensible systems.

Common tools:

1. The restify

2. The fast

3. The workflow

Workflow is built on top of restify and is able to define business processes for a range of remote services and apis. For example: error status, timeout, reconnection, congestion handling, etc.


Related articles: