콜백함수란?
콜백함수는 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다.
함수 안에서 특정한 시점에 콜백함수가 호출될때, 호출 시점에 제어권도 같이 넘어간다.
//콜백함수 예제 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는 함수가 어떻게 호출되냐에 따라 가리키는 값이 달라지기 때문 ↓ 아래참고 )
아래의 예제를 살펴보면,
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를 바인딩 해주어야 하는데,
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 객체 사용, 나머지 인자들은 배열 형태로 전달
자세한 예제는 아래 링크 참고 ⇩
콜백 지옥
콜백 지옥은 콜백함수를 익명함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 깊어지는 현상으로,
순차적 실행을 위해 콜백안에 콜백을 넣는 형태이다.
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 )
✔︎ 참고
[ 코어 자바스크립트 - 저자 정재남 ]
'JavaScript' 카테고리의 다른 글
[JavaScript] 프로토타입 (0) | 2020.11.19 |
---|---|
[JavaScript] 내부함수와 외부함수, 그리고 '클로저' (0) | 2020.11.17 |
[JavaScript] 명시적으로 this를 바인딩하는 방법 (0) | 2020.11.12 |
[Javascript] 자바스크립트의 this (0) | 2020.11.11 |
[Javascript] 실행 컨텍스트와 호이스팅, 스코프체인 (0) | 2020.11.03 |