[Package]async와 자바스크립트에서의 동기화
nodejs에서는 io나 db입출력에 관한건 비동기식으로 처리한다.
비동기에서 잘 모르는 사람은 그냥 원래 흐름(동기)과 다르게 작동한다고 생각하면 된다.
이벤트 핸들링 방식이라고 생각해도 무방하다. 조금은 다르지만.
이 방식은 명확한 장점과 명확한 단점을 동시에 가지게 된다.
일단 장점은 CPU 유휴시간이 없으므로 고성능을 발휘한다. 또한 쓰레드처럼 컨텍스트 스위칭이 일어나지 않으므로 원코어의 쓰레드보다도 성능이 좋다.
물론 쓰레드와는 스타일이 좀 다르므로 뭐가 좋다고 딱 말할수는 없다...
단점은 비동기이기 때문에 동시에 일어나서 루틴이 꼬일 수 있다는 것이다.
예를들어 아래의 코드를 보자.
router.get('/', function (req, res, next) {
var data;
db.put('ThisIsKey', 'ThisIsValue', function (err) {
if (err) {
console.log(err);
}
db.get('ThisIsKey', function (err, value) {
if (err) {
console.log(err);
}
console.log(value);
res.send(value);
});
});
});
위 코드는 nodejs의 express프레임워크 코드의 일부이다.
해당 코드는 총 3가지의 루틴이 있는데 DB에 저장을하는 put과 DB의 데이터를 가져오는 get 그리고 화면에 렌더링해주는 res.send로 3가지가 있다.
왜 코드가 이렇게 콜백을 사용해서 들여쓰기로 되있느냐...
그 이유는 비동기로 동작하기 때문이다.
요청하는 타이밍은 정해지지만 응답받는 타이밍은 랜덤이기 때문에 콜백으로 코딩할 수 밖에 없다.
잘 생각해보면 알겠지만 db의 데이터를 넣어야 db를 가져오는게 가능하고 db에서 데이터를 가져와야 화면에 그 데이터로 출력하는게 가능하다.
문제는 이 3가지는 우선순위를 가진다. 결국 콜백으로 코딩할 수 밖에 없다.
이러한걸 콜백 지옥이라고하는데 지금은 3단계 밖에 안되지만 경우에 따라서는 10계단을 내려갈 수도 있다.
그러면 영영 이런식으로 써야하느냐? 그렇지않다.
이러한 콜백지옥(이걸 검색해본 사람들은 모두 알겠지만 지옥이라는 말이 딱 적당하다.)을 해결하는 방법이 있다.
방식은 여러가지가 있는데 그 중에서 가장 대표적인 방식이 async 패키지를 사용하는 것이다.
npm install async -save
위와같이 해서 async를 패키지에 추가하자.
이제 패키지에 추가된게 확인되었다. 사용하여 보자.
var async = require('async');
패키지를 사용하기 위해서 반드시 require시켜줘야한다. 굳이 설명하지 않아도 필수이다.
const task1 = function (callback) {
db.put('ThisIsKey', 'ThisIsValue', function (err) {
if (err) {
console.log(err);
}
console.log('task1');
callback(null);
});
};
const task2 = function (callback) {
db.get('ThisIsKey', function (err, value) {
if (err) {
console.log(err);
}
data = value;
console.log('task2');
callback(null);
});
};
const task3 = function (callback) {
res.send(data);
console.log('task3');
callback(null);
};
그 다음 세가지의 루틴을 쪼개서 각각의 변수에 담는다.
이때 변수는 함수로 담아야한다.
그리고 꼭 callback(null)을 선언해줘야한다.
이 선언의 의미는 callback이 끝났다고 알려주는 것이다.
const tasks = [task1, task2, task3]
async.series(tasks);
이제 마지막으로 세개의 루틴을 하나의 리스트에 담고 나서
asun.series에 담는다. 여기서도 콜백을 써도된다. 본인의 자유.
asyn.series(tasks,callback);
이제 비동기 루틴들이 하나의 루틴으로 작동하는걸 확인할 수 있다.
비동기를 처리하는 방법은 이 외에도 여러가지가 있다.
그러니 다른 방법을 찾아서 사용하는것도 좋은 방법이다.