본문 바로가기

JavaScript

[JavaScript] 콜백함수의 this와 콜백지옥

728x90
반응형

콜백함수란?

콜백함수는 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다.

함수 안에서 특정한 시점에 콜백함수가 호출될때, 호출 시점에 제어권도 같이 넘어간다.

 

//콜백함수 예제 1
[1,2,3].forEach(el=>console.log(el))  // 1 2 3


//콜백함수 예제 2
const cbFunc = () =>{
  console.log('콜백함수 호출')
}

const func = (text,callback) => {
  console.log(text);
  callback()
}

func('함수호출',cbFunc)
// '함수호출'
// '콜백함수 호출' 

 

 

콜백함수의  this

객체의 메서드를 콜백함수로 사용하면,

메서드가 함수로서 호출되면서 객체와의 연결성이 사라져 this가 달라진다.

(this는 함수가 어떻게 호출되냐에 따라 가리키는 값이 달라지기 때문  ↓ 아래참고  )

 

[Javascript] 자바스크립트의 this

this라는 의미는 그냥 당장 지금 호출된 함수라던가 그 내부 변수를 가르킬것 같지만 직접 코딩을 하다보면 this가 생각과 다른것을 가르키고 있을때가있다. 그래서 this에 대해 정확히 정리하고

im-designloper.tistory.com

 

아래의 예제를 살펴보면,

const user = {
  name: null,
  setName : function(name){
    this.name = name
  }
}

function setUserName(name,callback){
  callback(name)
}

setUserName('IU',user.setName)

console.log(user.name) // null
console.log(window.name)  // 'IU'

setUserName이라는 함수는 두개의 매개변수를 입력받는다.

 

위와 같은 과정을 거쳐서 

user 안에 있는 setName을 호출해서 this.name을 'IU'라고 설정해 줬으니

user.name이  'IU'일 거라고 생각하지만, 

결과와 같이 console로 확인해 보면

user.name이 아닌 window.name에 'IU'가 찍혀있다.

 

 

 

이유는 위에서 얘기한 바와 같이 

 

1 )  메서드가 함수로서 호출되면서 객체와의 연결성이 사라져 this가 달라졌기 때문이고,

2 ) 그래서 this가 그냥 this로 불렸기 때문에 this는 user가 아닌 전역객체 (window)를 바라보기 때문이다.

 

메서드를 콜백함수 내에 호출했을때 this 확인하기

 

 

콜백함수의 this 바인딩

 

위와 같은 문제가 생기지 않게 하려면 콜백함수 호출시 this를 바인딩 해주어야 하는데,

call, apply, bind 등을 사용하여 this를 바인딩 해 줄수 있다.

const user = {
  name: null,
  setName : function(name){
    this.name = name
  }
}

// apply 사용 예제
function setUserName(name,callback,thisObj){
  callback.apply(thisObj,[name])
}

setUserName('IU',user.setName,user)

console.log(user.name) //'IU'


//call 사용 예제
function setUserName(name,callback,thisObj){
  callback.call(thisObj,name)
}

setUserName('IU',user.setName,user)

console.log(user.name) //'IU'
- call() : 첫 번째 인자로 this 객체 사용, 나머지 인자들은 , 로 구분
- apply() : 첫 번째 인자로 this 객체 사용, 나머지 인자들은 배열 형태로 전달

   자세한 예제는 아래 링크 참고 ⇩   

 

[JavaScript] 명시적으로 this를 바인딩하는 방법

앞서 정리한 내용에서 this는 실행 컨텍스트가 생성될때 결정되고, 어떻게 불리느냐에 따라서 this가 달라지며, 어떤 상황에서 전역객체를 가리키고, 렉시컬 객체를 가르키는지 정리했었다. 그 중

im-designloper.tistory.com

 

 

 

콜백 지옥

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

순차적 실행을 위해 콜백안에 콜백을 넣는 형태이다.

function add(x, callback) {
    let sum = x + x;
    console.log(sum);
    callback(sum);
}

add(2,res=>{
  add(res, res=>{
    add(res, res=>{
      console.log('finish')
    })
  })
})

//  4
//  8
//  16
// 'finish'

위의 add 함수는 x라는 매개변수를 더하고,

그 값을 인자로 사용하는 함수를 두번째 매개변수로 받는 함수이다.

 

 

add 함수는 아래와 같은 역할을 한다. 

예제를 실행했을때 다음과 같은 실행순서가 되고,

 

첫번째 인자를 두번 더한 값을

두번째 인자로 들어오는 콜백함수에 넣어서 실행하는 형태이다

 

이벤트 처리나 서버 통신을 위한 비동기 처리로 콜백 패턴을 사용하여

처리순서를 보장하기 위해 콜백함수가 네스팅 되어 복잡도가 높아지는 경우에 이런 형태가 등장한다.

 

 

이렇게 되면 보기도 어렵고, 복잡도가 높아져

보기 쉽게 하용하고 편리하게 사용하기 위해 Promise를 사용한다.

 

 

* Promise

비동기를 간편하게 처리할 수 있도록 도와주는 오브젝트로,

정해진 장시간의 기능을 수행하고 나서 정상적으로 기능이 수행되어졌다면,

성공의 메세지와 함께 처리된 결과값을 전달 ( resolve ) 
만약 기능을 수행하지 못해서 문제가 발생햇다면 에러를 전달해 준다 ( resect )

 

 

 

 


✔︎ 참고

[ 코어 자바스크립트  - 저자 정재남 ]

velog.io/@minidoo/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BD%9C%EB%B0%B1-%ED%95%A8%EC%88%98Callback-Function

 

728x90
반응형