ES2015 이후의 비동기 제어 흐름 패턴
아직 자바스크립트를 사용해보지 않아, 콜백지옥이 얼마나 심각한지는 모른다. 뭐 무튼 불편하니까 계속 대안이 나오고 있지 않을까?
이번 포스팅에서 유명한 대안책인 Promises, Generators / async, await ( ECAMA 2017 ) 에 대해 알아볼 것이다.
Promises
Promise는 비동기 작업의 결과를 제어할 수 있는 object를 반환해주는 함수이다. ( 말이 이해하기 힘들다.... 그냥 비동기 작업의 결과가 성공/실패일 때 제어할 수 있도록 제공해주는 함수이다.)
promise.then([onFulfilled], [onRejected])
기존의 콜백 지옥
asyncOperation(arg, (err, result) => { if(err) { //handle error } //do stuff with result });
Promise를 사용한 구조
asyncOperation(arg) .then(result => { //do stuff with result }, err => { //handle error });
Promise가 필요한 이유?
프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용됩니다. 아래코드는 일반적으로 사용되는 것입니다.
$.get('url 주소/products/1', function (response) {
// ...
});
데이터를 받아오기전에 화면에 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다.이를 해결하기 위한 방법 중 하나가 Promise 입니다.
Promise의 상태
- Pending ( 대기 ) : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled ( 이행 ) : 비동기 처리가 완료되어 결과값을 반환해준 상태
- Rejected ( 실패 ) : 비동기 처리에서 오류가 난 상태
이때까지 이해한 Promise를 바탕으로 하나의 예제를 작성해 봤습니다. 아래 코드는 서버 products/1로부터 data를 받아 제대로 된 값이 오면 resolve처리하고, 실패하면 reject 처리하는 것 입니다.
function getData() {
return new Promise(function (resolve, reject) {
$.get('url 주소/products/1', function (response) {
if (response) {
resolve(response);
}
reject(new Error("Request is failed"));
});
});
}
// Fulfilled 또는 Rejected의 결과 값 출력
getData().then(function (data) {
console.log(data); // response 값 출력
}).catch(function (err) {
console.error(err); // Error 출력
});
또 다른 예제를 살펴보면, 사용자 정보를 받아와 파싱하고, 인증하고 등등 작업하는 것입니다. 그리고, 아래 코드처럼 프로미스를 연결하여 사용할 수도 있습니다.
getData(userInfo)
.then(parseValue)
.then(auth)
.then(diaplay);
var userInfo = {
id: 'test@abc.com',
pw: '****'
};
function parseValue() {
return new Promise({
// ...
});
}
function auth() {
return new Promise({
// ...
});
}
function display() {
return new Promise({
// ...
});
}
Node.js 스타일 : promisify
module.exports.promisify = function(callbackBasedApi) { return function promisified() { const args = [].slice.call(arguments); return new Promise((resolve, reject) => { //[1] args.push((err, result) => { //[2] if(err) { return reject(err); //[3] } if(arguments.length <= 2) { //[4] resolve(result); } else { resolve([].slice.call(arguments, 1)); } }); callbackBasedApi.apply(null, args); //[5] }); } };
'Back-End > NodeJS' 카테고리의 다른 글
노드 프로젝트를 깔끔하게 작성하기 (0) | 2019.02.21 |
---|---|
3. 노드 기능 알아보기 (0) | 2019.02.14 |
1. Node.js 개요 (0) | 2019.01.09 |
1. Asynchronous Event-Driven 프로그래밍에 관하여 - Mastering Node.js (0) | 2019.01.03 |
0.노드란 무엇인가? - Mastering Node.js (0) | 2019.01.03 |