async 모듈을 이용한 비동기 처리 패턴 정리.
async 모듈 : https://github.com/caolan/async
series(tasks, [callback])
주어진 함수 배열(혹은 object)을 순서대로 실행 시킴.
모든 함수 실행이 끝나면 callback이 호출됨.
함수 실행 중 err가 있으면 그 이후로는 실행 중단.
// 함수를 배열로 전달
// __________________________________________________
async.series([
// 1st
function(callback){
callback(null, 1);
},
// 2nd
function(callback){
callback(null, 2);
}
],
// callback (final)
function(err, results){
console.log(err); // null
console.log(results); // [1, 2]
});
// 함수를 object로 전달. final callback의 result가 좀 더 가독성 있음
// __________________________________________________
async.series({
func1: function(callback){
callback(null, 1);
},
func2: function(callback){
callback(null, 2);
}
},
// callback (final)
function(err, results){
console.log(err); // null
console.log(results); // {func1: 1, func2: 2} <- 여기가 가독성..
});
// setTimeout으로 실행순서 확인
// __________________________________________________
// func1의 timeout이 1초로 func2의 0.5초보다 길지만 func1이 먼저 출력되고, func2가 출력됨
async.series({
func1: function(callback){
setTimeout(function(){
console.log('func 1');
callback(null, 1);
}, 1000);
},
func2: function(callback){
setTimeout(function(){
console.log('func 2');
callback(null, 2);
}, 500);
}
},
// callback (final)
function(err, results){
console.log(results); // {func1: 1, func2: 2}
});
// func1에 error가 있을 경우 func2는 실행되지 않음
// __________________________________________________
async.series({
func1: function(callback){
callback('error', 1);
},
func2: function(callback){
callback(null, 2);
}
},
// callback (final)
function(err, results){
console.log(err); // 'error'
console.log(results); // {func1: 1}
});
parallel(tasks, [callback])
주어진 함수 배열(혹은 object)을 동시에 실행 시킴. (함수실행순서를 알 수 없음)
모든 함수 실행이 끝나면 callback이 호출됨.
함수 실행 중 err가 있으면 그 이후로는 실행 중단.
// 전역변수 카운터
var i = 0;
// task로 사용할 함수
var f = function(callback){
++i;
// 2의 배수일 경우 1초 후 callback 호출
if (i%2===0) {
console.log('delay = '+i);
setTimeout(function(){
callback(null, i);
return;
}, 1000);
}
// 2의 배수가 아닐 경우 즉시 callback 호출
else {
console.log('no delay = '+i);
callback(null, i);
}
}
// 할당할 tasks 세팅
var tasks = {};
for (var j=0; j<5; j++) {
tasks['func'+j] = f;
}
// parallel!
async.parallel(tasks,
// callback
function(err, results){
console.log(results);
});
/*
[실행결과]
먼저 tasks로 지정된 함수 내부에서 console.log로 출력한
아래의 5라인이 주루룩 나온다. i 값을 1씩 증가시킨 정상적인 출력이다.
no delay = 1
delay = 2
no delay = 3
delay = 4
no delay = 5
그리고 대략 1초 후 final callback 함수에서 호출한 console.log 의 결과는 다음과 같다.
{func0: 1, func2: 3, func4: 5, func1: 5, func3: 5}}
++i 값이 2의 배수가 아닌 func0, func2, func4 함수의 callback result가 앞부분에 있고,
++i 값이 2의 배수인 func1, func3 함수의 callback result가 뒷부분에 있는 것을 확인할 수 있다.
그리고 func1, func3의 callback result인 i값이 둘 다 i의 최대값이 5인 것을 확인할 수 있다.
setTimeout 으로 지연되고 있는 동안 전역변수 i 는 이미 5가 되어 있기 때문이다.
*/
parallelLimit(tasks, limit, [callback])
주어진 함수 배열(혹은 object)을 동시에 실행 시킴. (함수실행순서를 알 수 없음)
parallel과 다른 점은 동시 실행되는 task의 숫자를 limit를 통해 조절할 수 있는 것.
I/O 등을 조절하는데 사용가능.
모든 함수 실행이 끝나면 callback이 호출됨.
함수 실행 중 err가 있으면 그 이후로는 실행 중단.
async.parallelLimit({
func1: function(callback){
console.log('func1');
setTimeout(function(){
callback(null, 1);
}, 1000);
},
func2: function(callback){
console.log('func2');
setTimeout(function(){
callback(null, 2);
}, 1000);
},
func3: function(callback){
console.log('func3');
setTimeout(function(){
callback(null, 3);
}, 1000);
}
},
// limit. 동시 실행 task수는 2로 지정
2,
// callback (final)
function(err, results){
console.log(results);
});
/*
[실행결과]
각 task에서 실행한 console.log 중
func1
func2
가 출력된 다음,
limit에 지정된 task수 2개가 이미 실행 중이므로 대기하고 있다가,
func1 또는 func2 가 callback을 호출하고 한자리가 비면,
func3 이 실행되면서
func3
이 출력되고,
또 다시 1초 가량 지연되다가 func3까지 모든 task가 callback을 호출하면,
final callback에서 호출한 console.log가 실행됨.
{func1: 1, func2: 2, func3: 3}
*/
waterfall(tasks, [callback])
기본적으로는 task가 순서대로 실행된다는 점에서 series와 같지만 다른 점은 다음과 같음.
1. result가 final callback에 전부 모이는 게 아니라 실행되는 각 task들 사이로 전달됨.
2. tasks는 object가 아닌 array만 가능
간단하게 표현하자면 args 전달이 자유로운 method chain.
async.waterfall([
// func1
function(callback){
// '111', 'one'이란 문자열을 인자로 다음함수 func2(callback) 호출
callback(null, '111', 'one');
},
// func2 (args 2개 지정)
function(arg1, arg2, callback){
console.log('func2 args = '+arg1+', '+arg2);
// '222'란 문자열을 인자로 다음함수 func3(callback) 호출
callback(null, '222');
},
// func3
function(arg, callback){
console.log('func3 args = '+arg);
// 'three'란 문자열을 인자로 final callback 호출
callback(null, 'three');
}
],
// callback (final)
function(err, result){
console.log(result); // results가 아니고 result임
});
/*
[실행결과]
func2 args = 111, one
func3 args = 222
'three'
*/
'node.js' 카테고리의 다른 글
[node.js] 인터넷 연결상태 체크 (check internet connectivity) (0) | 2016.01.13 |
---|---|
[node.js] http + cluster 구성시 worker graceful restart (no downtime) (0) | 2015.11.19 |
[node.js] http.request 지연현상 (delay) (0) | 2013.06.21 |
[node.js] node.js + MongoDB (node-mongodb-native) (0) | 2013.06.21 |
[node.js] 파일 터치하기 (touch, atime, mtime) (0) | 2013.01.22 |