TIL.60 Core J.S - 4. 콜백함수

Haiin·2021년 3월 4일
0

CoreJS

목록 보기
4/7
post-thumbnail

출저

  • 코어자바스크립트 - 정재남


콜백함수 (callback function)

고차함수의 인자는 콜백함수 이다.
다른 함수의 내부로 전달되는 함수가 콜백함수.
비동기 처리에 활용되는 함수.



1. 제어권

제어권과 관련이 깊다.
콜백 함수의 제어권을 넘겨받은 코드(함수 또는 메서드)는 콜백 함수 호출 시점에 대한 제어권을 가진다.

그럼, 어떤 제어권을 말하는가??


1.1 호출 시점

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

let count = 0
let cbFunc = function () {
  console.log(count)
  if (++count){
    clearIntercal(timer)
  }
}
let timer = setIntercal(cbFunc, 300)
// 0 (0.3초)
// 1 (0.6초)
// 2 (0.9초)
// 3 (1.2초)
// 4 (1.5초)
  • 위의 cbFunc 함수를 보면 cbFunc() 와 같이 바로 실행될 때와는 다르게 setIntercal(cbFunc, 300) 와 같이 setIntercal 안에 있을때는 실행시키는 주체가 다르다.
  • setIntercal 함수가 0.3초마다 cbFunc함수를 실행시키고 있는데 이는 함수 호출 시점에 대한 제어권을 가진다고 말할 수 있다.

1.2 인자

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

  • 예를 들어 map() 메서드를 사용한다고 생각한다면,
    arr.map(콜백(첫 번째 인자, 두 번째 인자, 세 번째 인자)) 은 이미 콜백함수를 받는다는 것이 약속되어 있고 그 콜백함수 안에 오는 첫 번째 인자는 map() 이 실행되는 대상의 arr 요소 하나 하나가 오게 될 것이고, 두 번째 인자는 index, 세 번째 인자는 실행되어 지는 arr가 오게 된다. 라는 약속이 이미 되어 있다.
    위를 생각한다면, 콜백을 실행시키는 주체인 map 메서드가 인자에 어떤 값들을 어떤 순서대로 넘길지에 대한 제어권을 가지고 있다고 말할 수 있다.

1.3 this

제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this 가 될 대상을 지정한 경우가 아닌 경우에는 콜백함수도 함수이기 때문에 기본적으로 this는 전역객체를 참조 한다.

setTimeout(function () {console.log(this)}, 300);
// Window {...}
[1, 2, 3, 4, 5].forEach(function (x){console.log(this)});
// Window {...}
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function (e){console.log(this, e)});
// <button id="a">클릭</button>...


2. 콜백 함수는 함수다

이 문장은 당연한 것 같지만 콜백함수 단원의 관점에서 얘기해보자면,
함수의 this 는 전역을 가리킨다. this 단원에서 배웠듯이 함수는 객체안에 할당되어 있더라도 호출되는 방식에 따라 (obj.function 과 같이 객체로 불리는 경우) 가 아닌 이상은 this 가 전역을 가리킨다.
위와 같은 방식을 콜백 함수도 따른다는 말이 콜백함수도 함수다 라는 말로 표현된 것 같다.
이 얘기는 참고로 this 단원에서도 잠깐 언급되었었다.



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

위의 말이 계속 반복되고 있지만 다른 말로 정리해 보자면, 객체의 메서드를 콜백 함수로 전달하면 해당 객체를 this 로 바라볼 수 없게 된다.

콜백 함수 내부에서 this 가 객체를 바라보게 하고 싶다면?

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

let obj2 = {name:'obj2'}
setTimeout(obj1.func.bind(obj2), 1500) //obj2
  • this 와 bind 메서드를 이용하여 콜백함수의 this 를 정해준다.


4. 콜백지옥과 비동기 제어

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

  • 기명함수로 변환
  • 비동기 작업의 동기적 표현 - Promise
  • 비동기 작업의 동기적 표현 - Generator
  • 비동기 작업의 동기적 표현 - Promise + Async/await


0개의 댓글