Node의 흐름 제어 (콜백지옥 탈출, Async, Promise)
1. 중첩 콜백
콜백지옥에 빠지기 쉬운 상황
- task1 실행 이후에 task2,3,4 등이 순차적 실행
- task1 실행 결과를 이용해 task2 가 실행
예제로 본다면 아래와 같은 상황이다.
task1(a, b, function(err, result1) {
task2(c, function(err, result2) {
task3...
task4...
});
});
2. Async
참조문서 : https://caolan.github.io/async/docs.html
외부모듈이기 때문에 npm install async로 설치한다.
행위 순서 제어
- series(tasks[, callback]) : 각 태스크는 함수이고, 중간에 에러가 나면 다음태스크를 실행하지 않고, 완료 콜백으로 에러를 전달한다. results에는 각 태스크의 결과가 배열로 전달된다.
function task1(callback) {
console.log('task1 message');
callback(null, 'result1');
}
function task2(callback) {
console.log('task2 message');
//callback(null, 'result2'); //정상
callback('fail', null); //에러
}
function task3(callback) {
console.log('task3 message');
callback(null, 'result3');
}
async.series([task1, task2, task3], function(err, results) {
if (err) {
console.log('error : ' + err);
} else {
console.log('task finish');
console.log(results);
}
}
);
- seriesEach
- waterfall(tasks[, callback]) : 태스크로 정보를 전달하려고 할때 사용하며, 다음 태스크로 전달할 값을 콜백의 파라미터로 준다. 태스크 함수의 파라미터로 이전 태스크의 값을 전달한다. results에는 마지막 태스크가 넘겨준 값만 갖고있는다.
async.waterfall([
function task1(callback) {
console.log('task1 message');
callback(null, 'result1');
},
function task2(arg, callback) {
console.log('task2 message' + arg);
callback(null, 'result2-1', 'result2-2');
},
function task3(arg1, arg2, callback) {
console.log('task3 message' + arg1 + arg2);
callback(null, 'result3');
}
],
function (err, results) {
console.log('task finish');
console.log(results);
}
);
- parallels(tasks[, callback]) : 여러 태스크를 동시에 실행한다. 모든 태스크를 마치면 완료 콜백이 실행된다.
console.time('PARALLEL_TIMER');
async.parallel([
function task1(callback) {
console.log('task1 start');
setTimeout(function() {
console.log('task1 end');
callback(null, 'result1');
}, 300);
console.log('task1 message');
},
function task2(callback) {
console.log('task2 start');
setTimeout(function() {
console.log('task2 end');
callback(null, 'result2');
}, 500);
console.log('task2 message');
},
function task3(callback) {
console.log('task3 start');
setTimeout(function() {
console.log('task3 end');
callback(null, 'result3');
}, 200);
console.log('task3 message');
}
],
function (err, results) {
console.log('task finish');
console.log(results);
console.timeEnd('PARALLEL_TIMER');
}
);
결과는 아래와 같다.
task1 start
task1 message
task2 start
task2 message
task3 start
task3 message
task3 end
task1 end
task2 end
task finish
[ 'result1', 'result2', 'result3' ]
PARALLEL_TIMER: 530.118m
콜렉션
콜렉션 내 각 항목을 사용하는 비동기 동작이다. 예를 들어 다수 파일을 비동기로 읽었을 때, 전부 다 읽었다는 걸 콜백으로 처리해주는 것이다.
- each(arr, iterator[, callback])
- forEachOf
- map, filter
3. Promise
참조문서 : https://www.promisejs.org/api/
비동기 동작의 흐름 제어할 때 사용한다. JavaScript ES6에 추가되었기 때문에, node에도 당연히 사용가능하다.
promise의 상태
- pending : 동작 완료 전, 여기서 성공과 실패가 된다.
- fullfilled : 비동기 동작 성공
- rejected : 동작 실패
promise 객체 생성 및 상태반영
new Promise(function (fullfill, reject) {
//비동기 동작
if (err)
reject(err);
else
fullfill(result);
})
promise 이후의 동작 : then
성공과 실패일 때 각각 콜백처리 한다.
new Promise(task).then(fullfilled, rejected);
function fullfilled(result) {}
function rejected(err) {}
보통 task()의 return으로 Promise 객체를 리턴한다. 성공 실패 비동기 처리할 수 있다.
function task(fullfill, reject) {
console.log('task start');
setTimeout(function() {
console.log('task end');
fullfill('task success');
}, 300);
}
function fullfilled(result) {
console.log('fullfilled : ', result);
}
function rejected(err) {
console.log('rejected : ', err);
}
new Promise(task).then(fullfilled, rejected);
출처: https://sjh836.tistory.com/83?category=710138 [빨간색코딩]
'JavaScript BackEnd > Node.js, Express' 카테고리의 다른 글
request 모듈 (0) | 2021.03.18 |
---|---|
Restify 모듈 (0) | 2021.03.18 |
Express 모듈 (0) | 2021.03.18 |
http 모듈 (0) | 2021.03.18 |
npm (0) | 2021.03.18 |
node의 기본모듈 (global, util, events, path, fs, url, querystring, cluster) (0) | 2021.03.18 |
Node.js의 기초(내부 아키텍처, 이벤트루프와 워커, 비동기의 이해) (0) | 2021.03.18 |
[NodeJS - Server] 프로젝트 폴더 세팅하기 (0) | 2021.03.17 |