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
筆者参考
札幌圏でリモート開発、在宅勤務を中心としたシステム開発の会社を経営しています。