4-1 콜백 함수란?

콜백 함수는 다른 코드(함수 또는 메서드)에게 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수이다.

4-2 제어권

4-2-1 호출 시점

let count = 0;
let cbFunc = function() {
  console.log(count);
  if (++count > 4) clearInterval(timer);
};
let timer = setInterval(cbFunc, 300);

// -- 실행 결과 --
// 0  (0.3초)
// 1  (0.6초)
// 2  (0.9초)
// 3  (1.2초)
// 4  (1.5초)

setInterval의 첫번째 인자로 cbFunc 콜백함수를 넘겨주니, setInterval이 cbFunc의 제어권을 넘겨 받는다.

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

4-2-2 인자

let newArr = [10, 20, 30].map(function(currentValue, index) {
  console.log(currentValue, index);
  return currentValue + 5;
});
console.log(newArr);

// -- 실행 결과 --
// 10 0
// 20 1
// 30 2
// [15, 25, 35]

map 메서드는 첫번째 인자로 callback 함수를 받고, 생략 가능한 두 번째 인자로 콜백 함수 내부에서 this로 인식할 대상을 특정할 수 있다. 두 번째 인자(thisArg)를 생략할 경우 일반적인 함수와 마찬가지로 this에 전역객체가 바인딩 된다.
map 메서드를 호출해서 원하는 배열을 얻으려면 map 메서드에 정의된 규칙(콜백 함수의 인자로 넘어올 값들 및 그 순서)에 따라 함수를 작성해야한다.
콜백 함수의 제어권을 넘겨받은 코드는 콜백 함수를 홏출할 때 인자에 어떤 값들을 어떤 순서로 넘길지에 대한 제어권을 가진다.

4-2-3 this

"콜백 함수도 함수이기에 기본적으로는 this가 전역 객체를 참조하지만, 제어권을 넘겨받을 코드에서 콜백 함수에 별도 this가 될 대상을 지정한 경우에는 그 대상을 참조하게 된다."

call/apply 메서드의 첫번째 인자로 콜백 함수 내부에서의 this가 될 대상을 명시적으로 바인딩한다.

setTimeout(function() {
  console.log(this);
}, 300); // (1) Window { ... } - 별도의 인자로 this를 넘겨주지 않음

[1, 2, 3, 4, 5].forEach(function(x) {
  console.log(this); // (2) Window { ... } - 별도의 인자로 this를 넘겨주지 않음
});

document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener(
  'click',
  function(e) {
    console.log(this, e); // (3) <button id="a">클릭</button>
  } // MouseEvent { isTrusted: true, ... } - addEventListener의 this를 넘겨줌
);

4-3 콜백 함수는 함수다

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

let obj = {
  vals: [1, 2, 3],
  logValues: function(v, i) {
    console.log(this, v, i); //
  },
};
obj.logValues(1, 2); // { vals: [1, 2, 3], logValues: f } 1 2

[4, 5, 6].forEach(obj.logValues); 
// console.log : Window { ... } 4 0
// console.log : Window { ... } 5 1
// console.log : Window { ... } 6 2

obj.logValues 메서드는 forEach의 콜백 함수로서 호출되었다. 따라서 별도로 this를 지정하는 인자를 지정하지 않았으므로 함수 내부에서 this는 전역객체를 바라본다.

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

bind 메서드를 이용하여 내부 함수에 this를 전달한다.

let obj1 = {
  name: 'obj1',
  func: function() {
    console.log(this.name);
  },
};
setTimeout(obj1.func.bind(obj1), 1000);

var obj2 = { name: 'obj2' };
setTimeout(obj1.func.bind(obj2), 1500);

4-5 콜백 지옥과 비동기 제어

동기적 코드 : 현재 실행 중인 코드가 완료된 후에야 다음 코드를 실행하는 방식
비동기적 코드 : 비동기적인 코드는 현재 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어간다.

비동기적인 코드를 동기적으로 작동하는 것처럼 보이게 하기 위해 Promise, async/await 도입

profile
🌱 매일 성장하는 개발자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN