Welcome to Github Repository, a front-end & algorithm open source blog that has been updated since 2018. At present, there are node learning, JS interview notes, CSS3 animation design, Webpack4 series tutorial, design mode, sword point Offer · JS version and other series.

Warehouse Address:Github.com/dongyuanxin…

Process: the Process module

The Process module is a tool provided by NodeJS for developers to interact with the current process. It provides a number of useful apis. From the document, a glimpse into the process module, further understanding and learning:

  • How do I handle command arguments?
  • How do I deal with the working directory?
  • How to handle exceptions?
  • How do I handle process exit?
  • The standard flow object of process
  • Understand process.nexttick in depth

How do I handle command arguments?

Command-line arguments refer to two things:

  • Parameters passed to node. For example,node --harmony script.js --version,--harmonyThese are the parameters passed to node
  • Parameters passed to the process. For example,node script.js --version --help,--version --helpIs the parameter passed to the process

They are obtained through process.argv and process.execArgv, respectively.

How do I deal with the working directory?

The current working directory can be obtained by using process.cwd().

The current working directory can be switched using process.chdir(directory), and an exception will be thrown if it fails. The practice is as follows:

function safeChdir(dir) {
    try {
        process.chdir(dir);
        return true;
    } catch (error) {
        return false; }}Copy the code

How to handle exceptions?

UncaughtException event

Nodejs can catch exceptions by try-catch. If the exception is not caught, the event loop bubbles from the bottom all the way through. If the exception that bubbles to the event loop is not handled, the current process will exit unexpectedly.

Uncaught exceptions can be handled by listening for uncaughtException events in process:

process.on("uncaughtException", (err, origin) => {
    console.log(err.message);
});

const a = 1 / b;
console.log("abc"); // Will not be executed
Copy the code

In the code above, the console output is: b is not defined. An error message was caught and the process exited with 0. In uncaughtException, developers can clear some allocated resources (file descriptors, handles, etc.). Restarting the process is not recommended.

UnhandledRejection event

If an exception for a Promise callback is not caught by.catch(), the unhandledRejection event of the process is emitted:

process.on("unhandledRejection", (err, promise) => {
    console.log(err.message);
});

Promise.reject(new Error("Error message")); // An exception that is not caught by a catch is handled by an unhandledRejection event
Copy the code

Warning events

Alarms are not an official part of the Node.js and Javascript error handling process. Node.js alerts you when it detects code practices that could lead to application performance issues, defects, or security concerns.

For example, in the previous code, a warning event is emitted if an exception occurs for an uncaught Promise callback.

How do I handle process exit?

process.exit() vs process.exitCode

A nodejs process that can exit directly by specifying the exit code through process.exit(). Direct use of process.exit() is not recommended, as this results in tasks in the event loop not being processed directly and may result in truncation and loss of data (such as stdout writes).

setTimeout((a)= > {
    console.log("I will not carry it out.");
});

process.exit(0);
Copy the code

The safe thing to do is to set process.exitCode and allow the process to exit naturally.

setTimeout((a)= > {
    console.log("I will not carry it out.");
});

process.exitCode = 1;
Copy the code

BeforeExit event

The events that handle process exit are: beforeExit event and exit event.

The beforeExit event is emitted when Node.js clears its event loop and has no other work to schedule. For example, if you need some asynchronous action before exiting, you can write it in the beforeExit event:

let hasSend = false;
process.on("beforeExit", () = > {if (hasSend) return; // Avoid endless loops

    setTimeout((a)= > {
        console.log("mock send data to serve");
        hasSend = true;
    }, 500);
});

console.log("...");
/ / output:
/ /...
// mock send data to serve
Copy the code

Note: Asynchronous tasks are added to the task queue again in the beforeExit event. After the task queue completes all tasks, the beforeExit event is triggered again. Therefore, if it is not processed, an infinite loop may occur. If exit() is called explicitly, this event is not emitted.

The exit events

In an exit event, only synchronous operations can be performed. The Node.js process will exit immediately after the ‘exit’ event listener is called, causing any other work still queued in the event loop to be abandoned.

The standard flow object of process

Process provides three standard flows. Note that some of them block synchronously at times (see documentation).

  • Process. stderr: type WriteStream,console.errorThe underlying implementation of the
  • Process. stdout: type WriteStream,console.logThe underlying implementation of the
  • Process. stdin: Type ReadStream, corresponding to keyboard input by default

Here is the code that reads console input and outputs in time based on the producer-consumer model:

process.stdin.setEncoding("utf8");

process.stdin.on("readable", () = > {let chunk;
    while((chunk = process.stdin.read()) ! = =null) {
        process.stdout.write(` > > >${chunk}`); }}); process.stdin.on("end", () => {
    process.stdout.write("The end");
});
Copy the code

Again, see stream’s documentation for the meaning of the event.

Understand process.nexttick in depth

When I first saw process.Nexttick, I was a little confused. As you can see from the documentation, it was used to put callback functions as microtasks in the task queue of the event loop. But what’s the point?

Because NodeJS is not suitable for computationally intensive applications, each process is a single thread, and at this point in time, only one event is executing. So, if our event consumes a lot of CPU time, subsequent events will have to wait a long time. So, one of nodeJS’s programming principles is to minimize the number of execution events per event. That’s what process.nextTick does, breaking up a large task into smaller tasks. Example code is as follows:

// Split into two functions
function BigThing() {
    doPartThing();

    process.nextTick((a)= > finishThing());
}
Copy the code

When do you execute the nextTick registration task in the event loop? Take a look at the following code:

setTimeout(function() {
    console.log("The first one second.");
    process.nextTick(function() {
        console.log("First 1 second: nextTick");
    });
}, 1000);

setTimeout(function() {
    console.log("Second one");
}, 1000);

console.log("I'm going to print 1.");

process.nextTick(function() {
    console.log("nextTick");
});

console.log("I'm going to print 2.");
Copy the code

NextTick is earlier than setTimeout:

I want to output1I want to output2NextTick first1seconds The first one1Second: nextTick first2a1secondsCopy the code

On the browser side, nextTick degrades to setTimeout(callback, 0). In NodeJS, however, use nextTick instead of setTimeout, which is more efficient and, strictly speaking, creates events in a different order in the task queue (see the previous code).

Child process: child_process module

Mastering nodeJS child_process module can greatly improve nodeJS development capabilities, such as master-slave processes to optimize CPU computing, multi-process development, and so on. This article describes the use of the CHILD_process module in the following aspects:

  • Creating a child process
  • Parent-child process communication
  • Independent subprocess
  • Process piping

Creating a child process

Nodejs’s child_process module creates child processes using the spawn, fork, exec, execFile methods. Their relationship is as follows:

  • Fork, exec, and execFile are all implemented through spawn.
  • Exec creates the shell by default. ExecFile doesn’t create a shell by default, which means you can’t use I/O redirects or file globs, but it’s more efficient.
  • Spawn, exec, and execFile all have synchronized versions that can cause processes to block.

Use child_process.spawn() :

const { spawn } = require("child_process");
// Return the ChildProcess object, on which stdio is not null by default
const ls = spawn("ls"["-lh"]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

ls.stderr.on("data", data => {
    console.error(`stderr: ${data}`);
});

ls.on("close", code => {
    console.log('Child process exits, exit code${code}`);
});
Copy the code

Use child_process.exec() :

const { exec } = require("child_process");
// Stdio is manipulated via callback functions
exec("ls -lh", (err, stdout, stderr) => {
    if (err) {
        console.error('Execution error:${err}`);
        return;
    }
    console.log(`stdout: ${stdout}`);
    console.error(`stderr: ${stderr}`);
});
Copy the code

Parent-child process communication

The ChildProcess object returned by fork() listens for message events on it to receive ChildProcess messages; Call the send method to implement IPC.

Parent-js code is as follows:

const { fork } = require("child_process");
const cp = fork("./sub.js");
cp.on("message", msg => {
    console.log("Parent process received message:", msg);
});
cp.send("I am the parent process");
Copy the code

The sub.js code is as follows:

process.on("message", m => {
    console.log("Child process received message:", m);
});

process.send("I'm the child process.");
Copy the code

Results after operation:

The parent process receives the message: I am the child process. The child process receives the message: I am the parent processCopy the code

Independent subprocess

Under normal circumstances, the parent process must wait for the child process to exit before exiting. If you want the parent process to exit first without being affected by the child process, you should:

  • On the ChildProcess objectunref()
  • options.detachedSet to true
  • The child process’s STDIO cannot be connected to the parent process

The main.js code looks like this:

const { spawn } = require("child_process");
const subprocess = spawn(process.argv0, ["sub.js"] and {detached: true.stdio: "ignore"
});

subprocess.unref();
Copy the code

The sub.js code is as follows:

setInterval((a)= > {}, 1000);
Copy the code

Process piping

The options.stdio option is used to configure the pipe between the parent and child processes. By default, the ChildProcess’s stdin, stdout, and stderr are redirected to the corresponding subprocess.stdin, subprocess.stdout, and subprocess.stderr streams on the ChildProcess object. This means that you can get the CHILD’s I/O in the parent process by listening for data events on it.

Can be used to “redirect” :

const fs = require("fs");
const child_process = require("child_process");

const subprocess = child_process.spawn("ls", {
    stdio: [
        0.// Use the parent's stdin for the child process.
        "pipe".// Pipe the child's stdout to the parent.
        fs.openSync("err.out"."w") // Direct the child's stderr to a file.]});Copy the code

Can also be used to implement “pipe operators” :

const { spawn } = require("child_process");

const ps = spawn("ps"["ax"]);
const grep = spawn("grep"["ssh"]);

ps.stdout.on("data", data => {
    grep.stdin.write(data);
});

ps.stderr.on("data", err => {
    console.error(`ps stderr: ${err}`);
});

ps.on("close", code => {
    if(code ! = =0) {
        console.log('Ps process exits, exit code${code}`);
    }
    grep.stdin.end();
});

grep.stdout.on("data", data => {
    console.log(data.toString());
});

grep.stderr.on("data", data => {
    console.error(`grep stderr: ${data}`);
});

grep.on("close", code => {
    if(code ! = =0) {
        console.log('grep Process exits. Exit code${code}`); }});Copy the code

Refer to the link

  • Nodejs V12 Stream document
  • Nodejs V12 process documentation
  • Nodejs study Notes
  • Build your NodeJS body of knowledge in one article
  • Node.js – Process learning Notes
  • glob
  • Nodejs: How to play child_process

In the last

  1. Please give me a thumbs up. Your support is the biggest incentive for me
  2. Welcome my public account: “Xin Tan blog”, only focus on the front end + algorithm original sharing