官术网_书友最值得收藏!

The process object

By now it should be clear as to how Node is structured, in terms of V8, the event loop, and so forth. We are now going to discuss, in detail, how instructions that you write (a JavaScript program) are compiled by V8 into a list of instructions whose execution context is accessible via the native Node process object.

The single thread forming the spine of Node's event loop is V8's event loop. When I/O operations are initiated within this loop they are delegated to libuv, which manages the request using its own (multi-threaded, asynchronous) environment. libuv announces the completion of I/O operations, allowing any callbacks waiting on this event to be re-introduced to the main V8 thread for execution:

The process object

Node's process object provides information on and control over the current running process. It is an instance of EventEmitter, is accessible from any scope, and exposes very useful low-level pointers. Consider the following program:

var size = process.argv[2];
var totl = process.argv[3] || 100;
var buff = [];
for(var i=0; i < totl; i++) {
  buff.push(new Buffer(size));
  process.stdout.write(process.memoryUsage().heapTotal + "\n");
}

Tip

Downloading the example code:

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Assuming the program file is named process.js, it would be executed like so:

> node process.js 1000000 100

This execution context first fetches the two command-line arguments via process.argv, builds a looping construct that grows memory usage depending on these arguments, and emits memory usage data as each new allocation is made. The program sends output to stdout, but could alternatively stream output to other processes, or even a file:

> node process.js 1000000 100 > out.file

In fact, the familiar console.log is implemented in the Node core as a wrapper around process.stdout.write:

 
  console.log = function (d) {
  process.stdout.write(d + '\n');
};

A Node process begins by constructing a single execution stack, with the global context forming the base of the stack. Functions on this stack execute within their own, local, context (sometimes referred to as scope), which remains enclosed within the global context (which you'll hear referred to as closure). Because Node is evented, any given execution context can commit the running thread to handling an eventual execution context. This is the purpose of callback functions.

Consider the following schematic of a simple interface for accessing the filesystem:

The process object

If we were to instantiate Filesystem and call readDir a nested execution context structure would be created: (global (fileSystem (readDir (anonymous function) ) ) ). The concomitant execution stack is introduced to Node's single process thread. This stack remains in memory until libuv reports that fs.readdir has completed, at which point the registered anonymous callback fires, resolving the sole pending execution context. As no further events are pending, and the maintenance of closures no longer necessary, the entire structure can be safely torn down (in reverse, beginning with anonymous), and the process can exit, freeing any allocated memory. This method of building up and tearing down a single stack is what Node's event loop is ultimately doing.

We'll explore the full suite of commands and attributes contained by the process object as we continue to develop examples and libraries in this book.

主站蜘蛛池模板: 金湖县| 集贤县| 河间市| 班玛县| 安溪县| 文昌市| 额尔古纳市| 巴塘县| 同心县| 双江| 台北市| 化隆| 大邑县| 保德县| 洮南市| 蛟河市| 溧水县| 胶州市| 荆州市| 肥城市| 拜泉县| 壶关县| 财经| 涿州市| 葵青区| 什邡市| 黄冈市| 托里县| 新化县| 商城县| 温州市| 九龙城区| 五家渠市| 凭祥市| 磐安县| 秦安县| 瑞丽市| 叙永县| 北宁市| 镇坪县| 南陵县|