[JS] Promise와 Callback 함수 비교
1. 비동기와 콜백
1) 콜백(Callback Function) : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수, 함수 안에서 실행되는 함수를 말합니다.
2) 고차 함수(Higher-Order Function) : 매개변수를 통해 함수의 외부에서 콜백 함수를 전달 받은 함수
function repeat(n,f) { // 외부에서 전달 받은 f를 n만큼 반복 호출 한다.
for (var i = 0; i< n; i++) {
f(i); // i를 전달하면서 f를 호출
}
}
function callMyName(name, callback){
alert(`${name}이 불려집니다.`);
callback(name);
}
function sayHello(name) {
alert(`안녕하세요 저는 ${name}입니다.`);
}
callMyName('Jin' , sayHello);
* 콜백함수는 보통 특정한 상황에 맞춰서 함수를 실행하고자 할 때 유용합니다.
3) 콜백함수와 this : this에 들어갈 매개변수를 명시해주지 않으면 전역 객체를 참조합니다.
해결 방안
call : ,를 기준으로 인자를 받음
* 함수.call(this로 쓸 객체, 인자1, 인자2, 인자3...);
function dispatchUserInfo(user,name,age,callback){
callback.call(user,name,age); // user 객체를 this로 쓰겠다
}
apply : 배열 형태로 인자를 받음
* 함수.apply(this로 쓸 객체, [인자1,인자2,인자3...]);
function dispatchUserInfo(user,name,age,callback) {
callback.apply(user, [name, age]);
bind : this를 지정만 해놓고 함수를 실행시키지는 않음
* apply, call은 this를 지정하면서 바로 함수 실행하지만 bind는 새로운 함수 리턴할 뿐 실행시키지는 않습니다.
*새로운 함수 = 함수.bind(this로 쓸 객체);
function dispatchUserInfo(user,name,age,callback){
const newCallback = callback.bind(user);
newCallback(name,age);
}
4) 비동기 : 함수나 일정한 코드가 실행 순서와 상관 없이 완료되는 것 즉 특정한 함수의 비동작 동작이 완료되기도 전에
다른 함수가 실행될 수 있다 <-> 동기 동작 : 일정한 순서대로 실행-완료, 실행-완료 되는 것을 말합니다.
* 비동기 동작이 완료되면 특정한 콜백 함수를 실행하라고 명시 한다면 동기 동작처럼 보이게 할 수 있어 유용합니다.
2. Promise
1) Promise : 제작자가 특정한 코드를 실행하면 소비자는 제작자가 실행한 코드의 결과에 따라 각기 다른 특정한 동작을 수행합니다 또 Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수를 인수로 전달받는데 이 콜백 함수는 resolve와 reject 함수를 인수로 전달받습니다.
const promise = new Promise((resolve,reject)=>{
if( /* 비동기 처리 성공 */){
resolve('result');
} else {
reject('failure reason');
}
});
2) Promise 상태 정보 : 현재 비동기 처리가 어떻게 진행되고 있는 지 알려줄 때 사용함
- pending : 비동기 처리가 아직 수행되지 않은 상태 (기본값)
- fulfilled : 비동기 처리가 수행된 상태(성공) -> resolve 함수 호출해 fulfilled로 변경
- rejected : 비동기 처리가 수행된 상태(실패) -> reject 함수 호출해 rejected로 변경
3) Promise의 후속 처리 메서드 : promise의 비동기 처리 상태가 변화할 시 이에 따른 후속 처리
- .then() : resolve, reject에 따른 결과 모두 처리 가능
new Promise(resolve => resolve('fulfilled'))
.then( v => console.log(v) , e => console.error(e));
new Promise((null , reject) => reject(new Error('rejected')))
.then(v=>console.log(v), e=> console.error(e));
- .catch() : 한 개의 콜백 함수를 인수로 전달 받는다. catch 메서드 콜백 함수는 프로미스가 rejectd 상태인 경우만 호출
new Promise((_,reject) => reject(new Error('rejected')))
.catch(e=> console.log(e));
- .finally() : finally 메서드는 한 개의 콜백 함수를 인수로 전달 받는다. fulfilled와 rejected 와 상관 없이 무조건 한 번 호출 됩니다. 즉, 상태와 상관 없이 공통적으로 수행되어야 할 처리 내용이 있을 때 유용합니다.
new Promise(()=>{})
.finally(()=>console.log('finally'));
4) 프로미스 체이닝
then , catch , finally 는 언제나 프로미스를 반환하기 때문에 연속적으로 호출할 수 있다. 이를 프로미스 체이닝이라 합니다. 순차적으로 처리해야하는 비동기 작업이 여러 개가 있는 경우에 유용합니다.
5) Callback과 Promise 비교
* 콜백 지옥을 예방하는 효과가 있습니다.
* 즉 함수의 처리 순서를 정하기 위해 Callback을 계속 사용해야 하는 문제가 생길 수 있습니다. 또 결괏값을 처리 할 때 callback 안에서만 볼 수 있고 callback 밖에서는 비동기에서 온 값을 알 수가 없습니다.
* 그러나 Promise는 Promise 객체에 비동기로 온 값이 저장되기 때문에 코드 작성과 가독성에서 유리함을 얻을 수 있습니다.