callback, promise, async/await

franchesca·2021년 8월 19일
0
post-thumbnail

📍 callback이란?

프로그래밍에서 콜백(callback) 또는 콜애프터 함수(call-after function)는 다른 코드의 인자로 넘겨주는 실행 가능한 함수를 말한다. 콜백을 넘겨받은 코드는 필요에 따라 이 함수를 곧바로 실행할 수도 있고, 나중에 실행할 수도 있다.

즉, 콜백함수는 나중에 호출되는 함수를 말합니다. 개인적으로 개념만을 두고 봤을 때는 '콜애프터'라는 명칭이 훨씬 잘 와닿는 것 같습니다.

  • 콜백 함수는 코드를 통해 명시적으로 호출하는 대신,
  • 코드 작성자는 함수를 등록하기만 하고,
  • 어떠한 이벤트가 발생하거나 특정 시점에 도달했을 때 실행되는 함수를 말합니다.
  • 예시) 자바스크립트 이벤트 핸들러
// onclick에 button1_click함수는 브라우저의 javascript API에서 DOM 이벤트 핸들러에 전달(등록)된다.
// 클릭 이벤트가 발생했을 때 이벤트 핸들러가 콜백 함수를 호출한다.

<button id="button1" onclick="button1_click();">버튼1</button>
<script>
  // [콜백 함수] button1_click
function button1_click() {
	alert("버튼1을 누르셨습니다.");
}
</script>

callback을 사용하는 이유

  • 자바스크립트에서 비동기적 프로그래밍을 할 수 있기 때문!
  • 콜백함수기법은 자바스크립트에서 가장 오래된 비동기적 메카니즘이라고 합니다.

🤔 비동기적 프로그래밍은 또 뭐죠?

이 글 한번 읽어보세요! 👉https://velog.io/@franchesca/%EB%B9%84%EB%8F%99%EA%B8%B0%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

콜백함수를 실행하는 시스템 함수

setTimeout 함수

  • setTimeout은 콜백함수를 지정해준 밀리초만큼의 시간 후에 실행하는 내장함수입니다.
  • 예시)
// 콜백 함수
function slowAlert() {
  console.log("That was really slow!");
}

console.log('we start here');

window.setTimeout(slowAlert, 2000);

console.log('we end here');

// [예상 결과]
// we start here
// That was really slow! --> 여기서 2초가 소요될 것으로 예상
// we end here

// [비동기적 프로그래밍 -- 실제 결과]
// we start here
// we end here
// That was really slow!
  • 위의 예시가 비동기적 프로그래밍인 이유는 setTimeout으로 인해 slowAlert 콜백 함수가 실행되는 2초 동안 블로킹이 일어나는 것을 막았기 때문입니다.

콜백함수의 단점

콜백 헬 (callback hell)

  • 콜백함수를 사용한 비동기식 처리모델은 블로킹 문제를 해결할 수 있다는 장점이 있습니다
  • 하지만 처리 순서를 보장하기 위해 여러 개의 콜백 함수가 네스팅(nesting, 중첩)되면 코드의 복잡도가 높아져 그야말로 헬입니다...
  • 이러한 현상을 콜벡 핼이라고 부릅니다
  • 콜백 헬은 코드의 가독성을 낮춥니다.
  • 예시)
step1(function(value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        step5(value4, function(value5) {
            // value5를 사용하는 처리
        });
      });
    });
  });
});

참고: https://www.hanumoka.net/2018/10/24/javascript-20181024-javascript-callback/
예시 참조: https://poiemaweb.com/es6-promise

📍 promise

  • 콜백 헬과 같은 문제를 해결하기 위해 프로미스가 등장했습니다.
  • promise는 promise 생성자 함수를 통해 인스턴스화합니다.
  • Promise 생성자 함수는 비동기 작업을 수행할 콜백 함수를 인자로 전달받는데, 이 콜백 함수는 resolve와 reject 함수를 인자로 전달받습니다.
  • promise의 반환값이 참이면 resolve 를 호출하고, 아닐시에는 reject 를 호출합니다.
  • resolve의 반환값에 대해서는 then()을, reject의 경우는 catch() 를 이용해서 결과값을 반환할 수 있습니다.
  • then()과 catch() 문의 체이닝을 통해 비동기 로직의 성공 여부에 따라 분기해서 처리가 가능합니다.
  • 예시)
const promise1 = function(param){
  return new Promise(function(resolve, reject){
    if(param){
      resolve("resolved");
    }
    else{
      reject("error");
    }
  });
}
//프로미스 실행
promise1(true)
.then((result) => {
  console.log(result);// "start" 출력
})
.catch((err) => {
  console.error(err);// "end" 출력
});

promise의 3가지 상태

  • Pending (대기) : 비동기 처리가 완료되지 않았을 경우입니다.
  • Fulfilled (이행) : 비동기 처리가 완료된 경우입니다.
  • Rejected (실패) : 비동기 처리 중 실패나 오류가 발생했을 경우입니다.

promise의 문제점

  • 콜백헬과 마찬가지로 꼬리에 꼬리를 무는 코드가 나올 수 있다는 문제점이 있습니다
  • 이와 같은 코드를 then hell이라고 부릅니다.

📍 async/await

  • 가장 최근에 등장한 비동기 처리 문법입니다.
  • 콜백이나 프로미스의 단점을 해소하기 위해 만들어졌습니다.
  • await는 async함수 안에서만 동작하고,
  • await를 통해서 Promise 반환 값을 받아 올 수 있습니다.
  • 예시)
(async (param) => {
  const promise2 = new Promise((resolve, reject) => {
    if (param) {
      resolve('resolved');
    } else {
      reject('error');
    }
  });

  try {
    const result = await promise2(true);
    console.log(result);
  } catch (err) {
    console.error(err);
  }
})();

promise와의 차이점은 뭔가요?

  1. promise의 경우는 catch() 문을 통해 에러 핸들링이 가능했습니다. 하지만 async/await의 경우는 이와 같은 기능이 없어 try-catch() 문을 활용해야 합니다.
  2. async/await는 비동기 코드를 동기 코드처럼 읽을 수 있어 코드의 흐름을 파악하기 쉽습니다.
  3. 코드가 길수록 async/await를 사용하면 앞서 언급한 then hell을 피할 수 있어 코드 가독성이 높아집니다.
profile
말하기 보다 생각하는, 생각하기보다 볼 줄 아는 개발자가 되려고 합니다✨

0개의 댓글