• No results found

Limited parallel

In document NodeJS book (Page 35-38)

});

}// Example task

function async(arg, callback) {

var delay = Math.floor(Math.random() * 5 + 1) * 100; // random ms console.log('async with \''+arg+'\', return in '+delay+' ms');

setTimeout(function() { callback(arg * 2); }, delay);

}

function final(results) { console.log('Done', results); } fullParallel([

function(next) { async(1, next); }, function(next) { async(2, next); }, function(next) { async(3, next); }, function(next) { async(4, next); }, function(next) { async(5, next); }, function(next) { async(6, next); } ], final);

Limited parallel

This is a bit more complicated, because we need to launch async tasks once other tasks finish, and need to store the result from those tasks back into the correct position in the results array. Details further below.

function limited(limit, callbacks, last) {

if(task == callbacks.length && running == 0) { last(results);

}

while(running < limit && callbacks[task]) { var callback = callbacks[task];

(function(index) { console.log('async with \''+arg+'\', return in '+delay+' ms');

setTimeout(function() { var result = arg * 2;

console.log('Return with \''+arg+'\', result '+result);

callback(result);

}, delay);

}

function final(results) { console.log('Done', results); } limited(3, [

function(next) { async(1, next); }, function(next) { async(2, next); }, function(next) { async(3, next); }, function(next) { async(4, next); }, function(next) { async(5, next); }, function(next) { async(6, next); } ], final);

We need to keep two counter values here: one for the next task, and another for the callback function.

In the fully parallel control flow we took advantage of [].forEach(), which returns the index of the currently running task in it's own scope.

Since we cannot rely on forEach() as tasks are launched in small groups, we need to use an anonymous function to get a new scope to hold the original index. This index is used to store the return value from the callback.

To illustrate the problem, I added a longer delay to the return from async() and an additional line of logging which shows when the result from async is returned. At that moment, we need to store the return value to the right index.

The anonymous function: (function(index) { ... } (task)) is needed because if we didn't create a new scope using an anonymous function, we would store the result in the wrong place in the results array (since the value of task might have changed between calling the callback and returning back from the callback). See the chapter on Javascript gotchas for more information on scope rules in JS.

7.4 The fourth control flow pattern

There is a fourth control flow pattern, which I won't discuss here: eventual completion. In this case, we are not interested in strictly controlling the order of operations, only that they occur at some point and are correctly responded to.

In Node, this can be implemented using EventEmitters. These are discussed in the chapter on Node fundamentals.

8. An overview of Node: Modules and npm

In this chapter, I:

discuss modules and process- related globals in Node recommend npm for package management, and show how:

it makes installing your own dependencies easier

it allows you to fetch external git repositories as dependencies and

it provides a standard vocabulary for running scripts, such as start and test

Node.js has a good amount of functionality built in. Let's look at the Table of Contents for the API documentation and try to group it into manageable chunks (italic = not covered here):

Fundament als Net work I/O File syst em I/O File System Path

Process I/O and V8 VM Terminal/console

REPL Readline TTY

Test ing & debugging Misc

I’ll go through the parts of the Node API that you’ll use the most when writing web applications. The rest of the API is best looked up from nodejs.org/api/.

Fundament als

The current chapter and Chapter 9.

Net work I/O

HTTP and HTTPS are covered in Chapter 10.

File syst em I/O

The file system module is covered in Chapter 11.

Process I/O and V8 VM Covered in Chapter TODO.

Terminal/console

REPL is discussed in Chapter TODO.

Test ing and debugging Coverage TODO.

8.1 Node.js modules

Let's talk about the module system in Node.

Modules make it possible to include other Javascript files into your applications. In fact, a vast majority of Node’s core functionality is implemented using modules written in Javascript - which means you can read the source code for the core libraries on Github.

Modules are crucial to building applications in Node, as they allow you to include external libraries, such as database access libraries - and they help in organiz ing your code into separate parts with limited responsibilities.

You should try to identify reusable parts in your own code and turn them into separate modules to reduce the amount of code per file and to make it easier to read and maintain your code.

Using modules is simple: you use the require() function, which takes one argument: the name of a core library or a file system path to the module you want to load. You’ve seen this before in the simple messaging application example, where I used require() to use several core modules.

To make a module yourself, you need to specify what objects you want to export. The exports object is available in the top level scope in Node for this purpose:

exports.funcname = function() { return ‘Hello World’;

};

Any properties assigned to the exports object will be accessible from the return value of the require() function:

var hello = require(‘./hello.js’);

console.log(hello.funcname()); // Print “Hello World”

You can also use module.exports instead of exports:

function funcname() { return ‘Hello World’; } module.exports = { funcname: funcname };

This alternative syntax makes it possible to assign a single object to exports (such as a class). We’ve previously discussed how you can build classes using prototypal inheritance. By making your classes separate modules, you can easily include them in your application:

// in class.js:

var Class = function() { … }

Class.prototype.funcname = function() {...}

module.exports = Class;

Then you can include your file using require() and make a new instance of your class:

// in another file:

var Class = require(‘./class.js’);

var object = new Class(); // create new instance

In document NodeJS book (Page 35-38)

Related documents