콜백 함수

최형필·2021년 2월 5일

코어자바스크립트

목록 보기
4/6

콜백 함수란?


https://media.vlpt.us/images/modolee/post/b743151c-c515-473d-847d-0909b4f31471/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-27%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.46.32.png

  • 콜백 함수는 다른 코드의 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수

제어권


호출 시점

  • 콜백 함수의 제어권을 넘겨받은 코드는 콜백 함수 호출 시점에 대한 제어권을 가진다

인자

  • 콜백 함수의 제어권을 넘겨받은 코드는 콜백 함수를 호출할 때 인자에 어떤 값들을 어떤 순서로 넘길 것인지에 대한 제어권을 가진다.

this

  • 콜백 함수에서 this를 지정할 수 있는 이유는 컨텍스트를 넘긴 후 콜백 함수 안에서 call/apply 함수를 사용해 컨텍스트를 바인딩 할 수 있기 때문이다.

콜백 함수는 함수다


  • 콜백 함수로 어떤 객체의 메서드를 전달하더라도 그 메서드는 메서드가 아닌 함수로서 호출된다.

콜백 함수 내부의 this에 다른 값 바인딩 하기


const obj1 = {
  name: 'obj1',
  func: function () {
    console.log(this.name);
  }
};

setTimeout(obj1.func.bind(obj1), 1000);
// 실행 결과
// obj1

const obj2 = { name: 'obj2' };
setTimeout(obj1.func.bind(obj2), 1500);
// 실행 결과
// obj2
  • es5에서 등장한 bind를 활용하면 깔끔하다

콜백 지옥과 비동기 제어


  • 콜백 지옥은 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상

이를 해결하기 위한 방법들

  1. 기명 함수로 변환
  2. Promise
const addCoffee = function (name) {
  return function (prevName) {
    return new Promise(function (resolve) {
      setTimeout(function () {
        const newName = prevName ? (prevName + ', ' + name) : name;
        console.log(newName);
        resolve(newName);
      }, 500);
    });
  }
};

addCoffee('에스프레소')()
  .then(addCoffee('아메리카노'))
  .then(addCoffee('카페모카'))
  .then(addCoffee('카페라떼'))
  1. generator
const addCoffee = function (prevName, name) {
  setTimeout(function () {
    coffeeMaker.next(prevName ? prevName + ', ' + name : name);
  }, 500);
};

const coffeeGenerator = function* () {
  const espresso = yield addCoffee('', '에스프레소');
  console.log(espresso);
  
  const americano = yield addCoffee(espresso, '아메리카노');
  console.log(americano);
  
  const mocha = yield addCoffee(americano, '카페모카');
  console.log(mocha);
  
  const latte = yield addCoffee(mocha, '카페라떼');
  console.log(latte);
};

const coffeeMaker = coffeeGenerator();
coffeeMaker.next();
  1. async/await
const addCoffee = function (name) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(name);
    }, 500);
  });
};

const coffeeMaker = async function () {
  let coffeeList = '';
  const _addCoffee = async function (name) {
    coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);
  };
  
  await _addCoffee('에스프레소');
  console.log(coffeeList);
  await _addCoffee('아메리카노');
  console.log(coffeeList);
  await _addCoffee('카페모카');
  console.log(coffeeList);
  await _addCoffee('카페라떼');
  console.log(coffeeList);

};

coffeeMaker();
profile
프론트엔드 개발자

0개의 댓글