15
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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については以下を参照のこと。
##リポジトリ
https://github.com/caolan/async

##公式ドキュメント
http://caolan.github.io/async/

##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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?