情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsで複数の独立した非同期的な処理を実行する

複数の独立した非同期的な処理を実行するにはasyncモジュールの下のような関数を使用します。

  • async.parallel関数
  • async.parallelLimit関数
  • async.series関数

処理を完全に並列的に実行したい場合にはasync.parallel関数を使用し、並列的に実行する処理の最大数を指定して実行したい場合にはasync.parallelLimit関数を使用し、直列的に実行したい場合にはasync.series関数を使用します。

なお、処理の実行中にエラーが発生しても既に開始している他の処理の実行は続行しますので注意してください。しかし、まだ開始していない処理の実行は行われません。

async.parallel関数とasync.series関数

var async = require('async');

async.parallel([
    function (callback) {
        callback(null, 'aaa');
        //or
        callback(new Error('bbb'), null);
    }, 
    function (callback) {
        callback(null, 'ccc');
        //or
        callback(new Error('ddd'), null);
    }
], function (err, results) {
});
async.series([
    function (callback) {
        callback(null, 'aaa');
        //or
        callback(new Error('bbb'), null);
    }, 
    function (callback) {
        callback(null, 'ccc');
        //or
        callback(new Error('ddd'), null);
    }
], function (err, results) {
});

第1引数

第1引数に複数の非同期的な処理を関数の配列として指定します。

この関数の第1引数はコールバック関数です。

処理が完了した場合や処理の実行中にエラーが発生した場合には必ずこのコールバック関数を呼び出さなければなりません。

このコールバック関数の第1引数にはエラーオブジェクト(エラーが発生しなかった場合にはnull)を指定し、第2引数には処理の結果(エラーが発生した場合にはnull)を指定します。

なお、処理は配列の最初の要素から順番に実行されます。

第2引数

第2引数に全ての非同期的な処理が完了したか、処理の実行中にエラーが発生した場合に呼び出されるコールバック関数を指定します。

この関数の第1引数はエラーオブジェクトであり、第2引数は全ての処理の結果を格納している配列です。この配列の要素の順序は第1引数の処理の配列の要素の順序に対応します。

この引数は指定しなくても構いません。

async.parallelLimit関数

async.parallelLimit([
    function (callback) {
        callback(null, 'aaa');
        //or
        callback(new Error('bbb'), null);
    }, 
    function (callback) {
        callback(null, 'ccc');
        //or
        callback(new Error('ddd'), null);
    }
], 10, function (err, results) {
});

async.parallel関数やasync.series関数とほぼ同じですが、第1引数と第2引数の間に並列的に実行する処理の最大数を指定します。

サンプルコード1

async.parallel関数の使用例です。

async-parallel.js

var async = require('async');
var util = require('util');

async.parallel([
    function (callback) {
        util.log('task 1 start.');
        setTimeout(function () {
            util.log('task 1 complete.');
            callback(null, 'task 1');
        }, 5000);
    }, 
    function (callback) {
        util.log('task 2 start.');
        setTimeout(function () {
            util.log('task 2 complete.');
            callback(null, 'task 2');
        }, 10000);
    }, 
    function (callback) {
        util.log('task 3 start.');
        setTimeout(function () {
            util.log('task 3 complete.');
            callback(null, 'task 3');
        }, 5000);
    }
], function (err, results) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        for (var i = 0; i < results.length; i++) {
            console.log(results[i]);
        }
    }
});

使用パッケージ

  • Async.js
    npm install asyncでインストールします。

実行結果

C:\work\node>node async-parallel.js
17 May 13:03:02 - task 1 start.
17 May 13:03:02 - task 2 start.
17 May 13:03:02 - task 3 start.
17 May 13:03:07 - task 1 complete.
17 May 13:03:07 - task 3 complete.
17 May 13:03:12 - task 2 complete.
task 1
task 2
task 3

サンプルコード2

async.parallelLimit関数の使用例です。

async-parallel-limit.js

var async = require('async');
var util = require('util');

async.parallelLimit([
    function (callback) {
        util.log('task 1 start.');
        setTimeout(function () {
            util.log('task 1 complete.');
            callback(null, 'task 1');
        }, 5000);
    }, 
    function (callback) {
        util.log('task 2 start.');
        setTimeout(function () {
            util.log('task 2 complete.');
            callback(null, 'task 2');
        }, 10000);
    }, 
    function (callback) {
        util.log('task 3 start.');
        setTimeout(function () {
            util.log('task 3 complete.');
            callback(null, 'task 3');
        }, 5000);
    }
], 2, function (err, results) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        for (var i = 0; i < results.length; i++) {
            console.log(results[i]);
        }
    }
});

使用パッケージ

  • Async.js
    npm install asyncでインストールします。

実行結果

C:\work\node>node async-parallel-limit.js
17 May 13:05:05 - task 1 start.
17 May 13:05:05 - task 2 start.
17 May 13:05:10 - task 1 complete.
17 May 13:05:10 - task 3 start.
17 May 13:05:15 - task 2 complete.
17 May 13:05:15 - task 3 complete.
task 1
task 2
task 3

サンプルコード3

async.series関数の使用例です。

async-series.js

var async = require('async');

async.series([
    function (callback) {
        var area = 1 * 1 * Math.PI;
        console.log('area of circle: r = 1 -> ' + area)
        callback(null, area);
    }, 
    function (callback) {
        var area = 2 * 2 * Math.PI;
        console.log('area of circle: r = 2 -> ' + area)
        callback(null, area);
    }, 
    function (callback) {
        var area = 3 * 3 * Math.PI;
        console.log('area of circle: r = 3 -> ' + area)
        callback(null, area);
    }
], function (err, results) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        var sum = 0;
        for (var i = 0; i < results.length; i++) {
            sum += results[i];
        }
        console.log('total: ' + sum);
    }
});

使用パッケージ

  • Async.js
    npm install asyncでインストールします。

実行結果

C:\work\node>node async-series.js
area of circle: r = 1 -> 3.141592653589793
area of circle: r = 2 -> 12.566370614359172
area of circle: r = 3 -> 28.274333882308138
total: 43.982297150257104

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js