15
22

More than 5 years have passed since last update.

【node.js】asyncで同期処理【サンプルリポジトリ公開】

Last updated at Posted at 2016-10-08

node.js では非同期の動きに苦労することが多いのですが、同期処理をサポートするモジュール「async」の動きを実際に動作できる形で紹介します。

asyncについて

assyncについては以下を参照のこと。

リポジトリ

公式ドキュメント

Node.jsへの導入

npm install async

使用例

series

順次処理

記述例

    console.log("-- Series test start ----------");
    async.series([
        function (callback) {
            console.log("1");
            setTimeout(function() {
                console.log("1 done");
                callback(null, 1);
            }, 100);
        },
        function (callback) {
            console.log("2");
            setTimeout(function() {
                console.log("2 done");
                callback("exit!", 1);
            }, 100);
        },
        function (callback) {
            console.log("3");
            setTimeout(function() {
                console.log("3 done");
                callback(null, 1);
            }, 100);
        },
    ], function (err, results) {
        if (err) {
            console.log("err[" + err + "]");
        }
        console.log("- Series test done [" + results + "] ----------");
    });
    console.log("Series test end of line");

結果

-- Series test start ----------
1
Series test end of line
1 done
2
2 done
err[exit!]

waterfall

順次処理(次の関数に値を渡せる)

記述例

    console.log("-- Waterfall test start ----------");
    async.waterfall([
        function (callback) {
            console.log("1");
            setTimeout(function() {
                console.log("1 done");
                callback(null, 1);
            }, 100);
        },
        function (arg, callback) {
            console.log("from:" + arg);
            console.log("2");
            setTimeout(function() {
                console.log("2 done");
                callback("exit!", 2);
            }, 100);
        },
        function (arg, callback) {
            console.log("3");
            setTimeout(function() {
                console.log("3 done");
                callback(null, 1);
            }, 100);
        }
    ], function (err, results) {
        if (err) {
            console.log("err[" + err + "]");
        }
        console.log("- Waterfall test done [" + results + "] ----------");
    });
    console.log("Waterfall test end of line");

結果

-- Waterfall test start ----------
1
Waterfall test end of line
1 done
from:1
2
2 done
err[exit!]
- Waterfall test done [2] ----------

eachSeries

コレクションの要素に基づいた同期処理

記述例

    console.log("-- EachSeries test start ----------");
    var a = [1,2,3,4,5,6,7,8,9,10];
    async.eachSeries(a, function(i, callback){
        setTimeout(function() {
            console.log('eachSeries : ' + i);
            if (i > 5) {
                callback("exit!");
            } else {
                callback(null);
            }
        }, 100);

    }, function(err){
        if (err) {
            console.log("err[" + err + "]");
        }
        console.log("- EachSeries test done" + " ----------");
    });
    console.log("EachSeries test end of line");

結果

-- EachSeries test start ----------
EachSeries test end of line
eachSeries : 1
eachSeries : 2
eachSeries : 3
eachSeries : 4
eachSeries : 5
eachSeries : 6
err[exit!]
- EachSeries test done ----------

mapSeries

コレクションの要素に基づいた同期処理(マップ使用)

記述例

    console.log("-- MapSeries test start ----------");
    var m = [
        { id: 1, value:'first' },
        { id: 2, value:'second' },
        { id: 3, value:'third' },
    ];
    async.eachSeries(m, function(item, callback){
        setTimeout(function() {
            console.log('mapSeries : id[' + item.id + '] value[' + item.value + ']');
            if (item.value == 'second') {
                callback("exit!");
            } else {
                callback(null);
            }
        }, 100);

    }, function(err){
        if (err) {
            console.log("err[" + err + "]");
        }
        console.log("- MapSeries test done" + " ----------");
        testComplete()
    });
    console.log("MapSeries test end of line");

結果

-- MapSeries test start ----------
MapSeries test end of line
mapSeries : id[1] value[first]
mapSeries : id[2] value[second]
err[exit!]
- MapSeries test done ----------

timesSeries

回数を指定しての同期処理

記述例

    console.log("-- TimesSeries test start ----------");
    async.timesSeries(10, function(i, callback){
        setTimeout(function() {
            console.log('timesSeries : ' + i);
            if (i > 5) {
                callback("exit!");
            } else {
                callback(null);
            }
        }, 100);

    }, function(err){
        if (err) {
            console.log("err[" + err + "]");
        }
        console.log("- TimesSeries test done" + " ----------");
        testComplete()
    });
    console.log("TimesSeries test end of line");

結果

-- TimesSeries test start ----------
TimesSeries test end of line
timesSeries : 0
timesSeries : 1
timesSeries : 2
timesSeries : 3
timesSeries : 4
timesSeries : 5
timesSeries : 6
err[exit!]
- TimesSeries test done ----------

組み合わせ

上記の複数の同期処理を呼ぶ出す同期処理

記述例

async.series([
    function (callback) {
        series.test(function() {
            callback(null, "series");
        });
    },
    function (callback) {
        waterfall.test(function() {
            callback(null, "waterfall");
        });
    },
    function (callback) {
        eachSeries.test(function() {
            callback(null, "eachSeries");
        });
    },
    function (callback) {
        mapSeries.test(function() {
            callback(null, "mapSeries");
        });
    },
    function (callback) {
        timesSeries.test(function() {
            callback(null, "timesSeries");
        });
    },
    function (callback) {
        each.test(function() {
            callback(null, "each");
        });
    },
], function (err, results) {
    if (err) {
        console.log("err[" + err + "]");
    }
    console.log('async test all done. ' + results);
});

サンプルコード

上記の処理を確認できるソースコードを下記に用意したので参考にしてください。
https://github.com/k-neo/tryAsync


筆者参考

札幌圏でリモート開発、在宅勤務を中心としたシステム開発の会社を経営しています。

ローラハウス

15
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
22