Node.js를 이용해 코딩을 하다보니 Javascript에서 쓰이는
콜백 패턴을 자주 사용하게 되는데, 함수를 사용하다보면
함수들을 실행하고자 할 때 코드가 복잡해지고 가독성이 떨어져
불편한 점이 이만저만이 아니였다.
그래서 이러한 단점을 보완하기 위해 Javascript에서 제공되는 프레임워크인
async를 사용해보고자 한다.
https://github.com/caolan/async
async는 자바스크립트의 고질적인 문제인 콜백 헬을 개선하기 위해서 개발되었다고 한다.
공식 Documentation을 읽어보면 async가 제공하는 다양한 기능들을 볼 수 있다.
https://caolan.github.io/async/v3/
Home - Documentation
For Async v1.5.x documentation, go HERE Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for use with Node.js and installable via npm i async, it can also b
caolan.github.io
본 글에서는 async가 콜백 헬을 벗어날 수 있게 제공하는 대표적인 기능 3가지만을 소개하고자 한다.
Documentation 페이지에 방문하면 async가 제공하는 기능 중
Control flow 탭에 우리가 사용하고자 하는 기능들이 있다.
살펴볼 기능 중 첫번째는 parallel이다.
1. parallel 을 이용한 흐름 제어
parallel은 여러 개의 tasks를 받아 동시에 실행하는 제어 방법을 사용한다. 이름에서 볼 수 있듯이
인자로 받은 여러 개의 tasks들을 동시에 병렬적으로 실행한다.
모든 tasks들의 수행이 끝나면 최종 callback에 결과물들을 배열 형태로 전달한다.
이 때 전달받을 수 있는 task들의 type은 array, iterable, asynciterable, object 타입이 있다.
유의해야 할 점은 이 parellel 기능이 병렬적으로 task를 수행한다고 해서 실제 멀티 쓰레드를
하는 것이 아니라는 점이다. 단지 멀티 쓰레드인 것처럼 수행한다.
documentation에서 제공하는 parallel의 예제는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
async.parallel([
function(callback) {
setTimeout(function() {
callback(null, 'one');
}, 200);
},
function(callback) {
setTimeout(function() {
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results) {
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
// an example using an object instead of an array
async.parallel({
one: function(callback) {
setTimeout(function() {
callback(null, 1);
}, 200);
},
two: function(callback) {
setTimeout(function() {
callback(null, 2);
}, 100);
}
}, function(err, results) {
// results is now equals to: {one: 1, two: 2}
});
|
cs |
parellel이 다수의 task들을 배열 형태로 전달받고 callback에 results가 담긴다는 것에 유의해야 한다.
실제로 console.log를 이용해 results를 보면 결과물들이 작업이 담긴 순으로 배열에 담겨 있는 것을 볼 수 있다.
2. waterfall을 이용한 흐름 제어
watarfall은 여러 개의 tasks들을 처리하는데 있어 앞의 task가 반환한 결과값을
다음 task의 인자로 사용하는 제어 흐름 방법을 사용한다.
이러한 제어 흐름을 통해 waterfall이라는 이름 그대로 연속적인 함수의 흐름을 쉽게
파악할 수 있어 코드의 가독성이 높아진다.
모든 task들의 수행이 끝나면 두번째 인자로 받은 callback 함수가 수행된다.
위의 parellel과 마찬가지로 callback 함수에 result를 담을 수도 있다.
parellel과 다른 점은 parellel이 tasks들을 array 뿐만 아니라 iterable, asynciterable, object로도 받을 수 있는데
비해서, waterfall은 tasks들을 array로만 받을 수 있다.
차례대로 시행되는 여러 task 중 하나라도 error가 뜬다면, waterfall은 다음 task의 수행을
멈추고 바로 두번째 인자의 callback의 에러를 호출한다
다음은 documentation에서 제공하는 waterfall 예제이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
// Or, with named functions:
async.waterfall([
myFirstFunction,
mySecondFunction,
myLastFunction,
], function (err, result) {
// result now equals 'done'
});
function myFirstFunction(callback) {
callback(null, 'one', 'two');
}
function mySecondFunction(arg1, arg2, callback) {
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
}
function myLastFunction(arg1, callback) {
// arg1 now equals 'three'
callback(null, 'done');
}
|
cs |
보이는 것처럼 function들은 이전 function의 결과값을 인자로 받아 차례대로 수행된다.
waterfall은 여러 task들이 서로 의존성을 가지고 있고 순차적으로 시행해야 할 때 유용하다.
유의할 점은, 마지막 callback에 선택적으로 result값을 받을 때
parellel과 달리 맨 마지막 task의 리턴값만을 넘겨 받는다는 점이다.
3. series를 이용한 흐름 제어
series는 parellel과 waterfall을 반반씩 합쳐놓은 흐름 제어를 사용한다.
waterfall과 동일하게 정의된 task들을 순서대로 시행하지만,
parellel과 동일하게 task들의 결과들을 최종 callback에 배열 형태로 넘겨준다.
waterfall과 마찬가지로 task 시행 도중 error 발생 시 마지막 callback으로 넘어간다.
전달받을 수 있는 tasks의 type은 parellel과 동일하게 array,iterable,asynciterable,object가 있다.
다음은 documentation에 나온 series의 예제이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
async.series([
function(callback) {
// do some stuff ...
callback(null, 'one');
},
function(callback) {
// do some more stuff ...
callback(null, 'two');
}
],
// optional callback
function(err, results) {
// results is now equal to ['one', 'two']
});
async.series({
one: function(callback) {
setTimeout(function() {
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function() {
callback(null, 2);
}, 100);
}
}, function(err, results) {
// results is now equal to: {one: 1, two: 2}
});
|
cs |
series는 기능들이 서로에 대한 의존성은 없지만 순차적으로 실행이 되어야 할 경우
유용하게 쓸 수 있다.
지금까지 async 모듈을 이용해서 Javascript의 문제점인 콜백헬을 해결하고 flow control을 통해
함수의 기능 순서 제어와 코드 가독성 개선하는 법을 알아보았다. 위의 3가지 흐름 제어 말고도
다양한 기능들이 존재하므로 async 공식 documentation을 통해 알아보자.
'JavaScript' 카테고리의 다른 글
Node.js를 이용해 채팅 웹 어플리케이션 따라 만들어보기 (0) | 2020.03.02 |
---|---|
Gulp로 JavaScript 반복 작업 자동화 빌드 도구 사용해보기 (0) | 2020.02.09 |