- Promise 는 JavaScript 비동기 처리에 사용되는 객체이다.
- Promise 의 주 사용처는 서버에서 받아온 데이터를 표시하는데 있다.
기초 학습
//인자로 함수를 받아 응답데이터를 매개 값으로 넘김
function getData(callbackFunc) {
$.get('url 주소/products/1', function(response) {
callbackFunc(response);
});
}
// tableData 로깅
getData(function(tableData) {
console.log(tableData);
});
Promise 사용
function getData(callback) {
// 프로미스 객체를 추가
return new Promise(function(resolve, reject) {// resolve, reject 콜백을 가지는 익명함수
$.get('url 주소/products/1', function(response) {// Ajax 콜을 하고 콜백을 받음
resolve(response);// resolve 함수가 실행됨
});
});
}
// getData()의 실행이 끝나면 then() 이 호출 됨
getData().then(function(tableData) {
// resolve() 결과 -> then() 의 함수인자에게 전달
console.log(tableData);
});
Promise 의 상태
- Pending : 대기 상태, 비동기 로직 미완료 상태
- Fulfilled : 이행 상태, 비동기 로직 완료로 Promise 가 결과 값을 리턴한 상태
- Rejected : 실패 상태, 비동기처리가 실패, 오류 발생 상태
//Pending , Promise 의 인자는 resolve, reject Function 이다.
new Promise( (resolve, reject) => {});
//Fulfilled , resolve 사용시 이행 상태
new Promise( (resolve, reject) => {
resolve();
} );
ex)
function getData() {
return new Promise( (resolve, reject) => {
const data = 100; // 로직
resolve(data);
} );
}
// Fulfilled 상태로 넘어가면 then( function ) 으로 결과 값을 받을 수 있다.
getData().then( (callbackData) => {
console.log(callbackData); // 100
} );
//Rejectd , reject 사용시 실패 상태
new Promise( (resolve, reject) => {
reject();
} );
ex)
function getData() {
return new Promise( (resolve, reject) => {
//로직
reject(new Error("Request is failed");
} );
}
// Rejected 상태로 넘어가면 catch( function ) 으로 결과 값을 받을 수 있다.
getData().then().catch( err => {
console.log(err);
} );
Ajax 를 통한 예제
function getData() {
return new Promise(function(resolve, reject) {// resolve, reject 는 Function
$.get('url/products/1', function(response) {//Ajax CallBack
if (response) {//Response 가 undefined 가 아니라면
resolve(response); //resolve 에 태워서 then() 으로 보냄
}
reject(new Error("Request is failed")); // undefined 라면 reject 에 태워서 catch() 로 보냄
});
});
}
getData().then(function(data) {// then( fnc ) 은 resolve 함수의 리턴 값을 받음
console.log(data);
}).catch(function(err) {// catch( fnc ) 은 reject 함수의 리턴 값을 받음.
console.error(err);
});
Promise Chain
- Promise 는 연결하여 사용할 수 있다.
- 아마 Builder 패턴 으로 then( fnc ) 은 메서드 체인을 위해 Promise 자신을 리턴할 거다. ( 개인적 생각 임 )
- then( fnc ) 를 연이어 이어주는 작업은 시간 차가 있어 Background 로 넘기는 게아니라 단순한 메서드 체인 과정으로 보인다.
- 리턴 값을 받아 단계를 거쳐서 작업해 주어야할때 유용하다.
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1); // Fulfilled 상태로 진입 resolve 에 태워서 then( fnc ) 호출
}, 2000);
})
.then((result) => {
//1
console.log(result);
return result + 10;
})
.then((result) => {
//11
console.log(result);
return result + 20;
})
.then((result) => {
//31
console.log(result);
});
심화 예제
const userInfo = {
id: 'test@abc.com',
pw: '****'
};
function getData(userInfo) {
console.log(`getData ${userInfo.id}`);
return new Promise( (resolve, reject) => {
resolve(userInfo.id);
} )
}
function parseValue(id) {
console.log(`parseValue ${id}`);
return new Promise( (resolve,reject) => {
resolve(id.split('').reverse().join(''));
});
}
function auth(reverseId) {
console.log(`auth ${reverseId}`);
reverseId += " :)";
return new Promise( (resolve, reject) => {
resolve(reverseId);
});
}
function display(str) {
console.log(`display ${str}` );
return new Promise((resolve, reject) => {
resolve(str);
});
}
getData(userInfo) // userInfo 의 resolve 에 응답이 태워지면
.then(parseValue) // then() 으로가서 parseValue 를 돌려서 응답을 resolve 에 태우고
.then(auth) // then() 으로가 auth 를 돌려서 응답을 resolve 에 태우고
.then(display) // then() 으로가 diaply 를 돌려서 응답을 resolve에 태워보낸다.
.then( (data) => {console.log(`result ${data}`);});
Promise 의 에러 처리
- Promise 오류 발생 시 처리방법에 대해 알아야한다. 2가지 방법을 제공한다.
- then( fnc ) 에 err 함수 인자를 추가하여 해결하는 방법 : .then( fnc, err )
- .catch( fnc ) 으로 체인하는 방법 : then( fnc ).catch( fnc );
- 두가지 방법 모두 Promise 에서 reject( Error ) 가 태워졌을 시 실행되는 방법이다.
function getData() {
return new Promise((resolve, reject) => {
reject('failed');
});
}
// then( fnc, err )
getData().then(() => {
},(err) => {
console.log(err);
});
// then( fnc ).catch( err );
getData().then().catch((err) => {
console.log(err);
});
- 하지만 Promise 에러 처리는 .catch( fnc ) 를 사용하는 것이 바람직 하다.
- resolve() 에 태워져 온 then( fnc ) 내부에서 발생하는 에러는 2번째 인자로는 해결할 수 없다.
- 하지만, .catch( fnc ) 로는 then( fnc ) 에서 발생하는 에러를 잡을 수 있다.
// then( fnc ,err) 로는 감지 불가
function getData() {
return new Promise((resolve, reject) => {
resolve('hi');
});
}
getData().then((result) => {
console.log(result);
throw new Error("Error in then()"); // Uncaught (in promise) Error: Error in then()
}, (err) => {
console.log('then error : ', err);
});
//catch( fnc ) 로는 감지 가능
function getData() {
return new Promise((resolve, reject) => {
resolve('hi');
});
}
getData().then((result) => {
console.log(result);
throw new Error("Error in then()"); //<<
}).catch((err) => {
console.log('then error : ', err);
});
참고
joshua1988.github.io/web-development/javascript/promise-for-beginners/
'Vue.js > Vue + ES6' 카테고리의 다른 글
async & await (0) | 2020.12.18 |
---|---|
JavaScript 의 비동기 처리 (0) | 2020.12.18 |
ES6 (0) | 2020.12.18 |