프로그래밍/JavaScript

[JS] Promise와 Callback 함수 비교

JellyApple 2023. 7. 31. 22:58

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 객체에 비동기로 온 값이 저장되기 때문에 코드 작성과 가독성에서 유리함을 얻을 수 있습니다.

'프로그래밍 > JavaScript' 카테고리의 다른 글

[모딥다] JS (3) - 스코프  (1) 2024.12.17
[모딥다] JS (2) - 함수  (0) 2024.12.11
[모딥다] JS (1) - 객체 리터럴  (0) 2024.12.10
JavaScript에서 비동기 처리하기  (0) 2024.12.01
[JS] JS 데이터 타입  (0) 2023.07.31