다른 코드의 인자(매개변수)로 전달하는 함수들은 모두 콜백함수라고 한다.
그리고, 콜백 함수를 사용하다 보면 콜백 지옥이라는 것을 볼 수 있으며,
콜백 지옥에서 벗어나기 위한 동기 비동기 처리를 자연스레 배울 수 있다.
ex) 콜백 지옥 예시
setTimeout(
function(name) {
var coffeeList = name;
console.log(coffeeList);
setTimeout(
function(name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function(name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function(name) {
coffeeList += ", " + name;
console.log(coffeeList);
},
500,
"에스프레소"
)
},
500,
"카페라떼",
)
},
500,
"카페모카"
)
},
500,
"아메리카노"
)
그리고 콜백 함수는 호출 시점과 인자에 대한 제어권도 가지게 된다.
제어권이란?
특정 객체가 어떤 처리를 하기 위한 결정권을 가지는 것
또한 콜백 함수는 인자로 함수를 전달하는 것이기 때문에 주체가 전역 객체를 향하게 된다.
그래서 명시적 바인딩을 통해 콜백함수에 this를 바인딩하는 방법이 있다.
call, apply, bind 방식으로 this를 바인딩할 수 있는데 가장 좋은 방법은 bind() 메서드를 사용하는 것이다.
bind는 this를 바인딩한 함수를 반환하고 반환된 함수를 기준으로 해당 함수를 실행하게 되므로 call이나 apply처럼 특정 변수에 할당할 필요없다는 점이 편리하다.
(call, apply 는 즉시 호출 메서드이기 때문)
동기와 비동기이다.
비동기는 어떠한 로직이 수행될 때 요청을 한 사용자가 응답을 받는 동안 자유로운 행동을 할 수 있다.
동기는 어떠한 로직이 수핼될 때 요청을 한 사용자가 응답을 받기 전까지 대기해야 한다.
콜백 지옥에 빠지는 이유는 가독성이 좋지 못하고, 비효율적인 코딩을 했기 때문이다.
콜백 지옥을 벗어나기 위해 사용하는 기법이 바로 비동기와 동기에 있다.
기본적으로 우리가 아는 코드 흐름은 바로 동기적 코드 흐름이다 (위에서 아래)
하지만 웹, 앱, 게임 등 다양한 곳에서 이벤트가 발생할때까지 대기하는 로직이나 서버 통신이 필요한 로직이 있을 것이다.
이벤트가 발생할때까지 대기하는 것은 어떻게 구현하는가?
서버통신이 된 다음 로직이 처리되도록 하는 것은 어떻게 구현하는가?
여기서 우리는 비동기를 사용하는 이유와 비동기를 동기적으로 수행하도록 하는 코드를 알아야 우리가 알맞은 순서와 로직처리를 구현할 수 있다.
비동기는 어떻게 구현하지?
이 부분은 콜백함수를 통해 구현했던 것이 바로 비동기적인 코드 흐름을 위해서였다.
setTimeout() 처럼 콜백함수와 ms단위의 초를 매개변수로 받는 함수처럼 코드 흐름이 지나갔음에도 Timer가 존재하여 설정한 초가 지난 이후에 처리되는 것.
또한 setTimeout() 이후의 일반 코드가 먼저 처리가 되는 것이 바로 비동기적인 흐름인 것이다.
그럼 어떻게 콜백 지옥을 벗어날까?
1. 기명함수 사용
2. Promise를 통한 동기적 흐름 표현 사용
3. (ES6) Generator를 사용한 동기적 흐름 제어
4. (ES6) Promise와 async await을 통한 동기적 흐름 제어
1번 기명함수는 선언하는 개수만큼 함수를 선언해줘야하기 때문에 비효율적인 방식이다.
2번 Promise는 resolve(성공) -> then '로직수행', reject(실패) -> catch '로직수행'을 통해 어떤 로직의 성공과 실패에 따른 로직을 동기적으로 바꾼 사례이다.
3번 Generator는 iterator(반복되는 객체)가 반환되고 next 메서드로 순환하는 기능을 가졌다.
하지만 순환을 제어할 수 없으면 사실상 반복문과 다름없다. 때문에 yield라는 키워드를 통해 수행을 잠깐 멈추고 다시 next 메서드가 호출될 때까지 대기하는 방식으로 흐름을 동기적으로 제어할 수 있다.
4번 async await의 경우 Promise로 반환 값을 받아야 하며, Promise가 반환되었는지 확인을 하여 순차적으로 수행이 되는 제어 방식이다. await을 주어 Promise 반환을 확인하게 되고, 이 과정에서 수행을 멈추기 때문에 동기적인 흐름을 만들 수 있다.
이전 주차에서는 CS와 더불어 기술적인 부분을 같이 배워 배워야할 지식이 방대했지만 이번 주차는 몇 안되는 주제이지만 백엔드를 배우면서 매우 중요하게 쓰여질 요소라고 느꼈습니다.
비동기 동기 처리에 대한 이해와 응용법을 익히고, 콜백함수에서 this 바인딩, 어떤 주체를 바라보고 있는지에 대해 명확하게 알고 있어야 한다고 생각했습니다.
콜백함수와 this 바인딩, 콜백함수와 콜백지옥에서 보다 효율적이고 가독성이 좋게 코딩하는 방법과 예시를 알 수 있었습니다.
또한 비동기 동기 처리를 통해 사용자가 원하는 로직 순서에 의해 처리되도록 설계하는 방법과 그런 방법은 다양하게 마련되어 있다는 점을 알 수 있었습니다.
ES6 버전으로 업데이트 되면서 이전에 겪을 수 있었던 문제나 불편함이 새로운 기술을 통해 개선된 점도 배울 수 있어 좋았습니다.
이전 주차에 배웠던 this와 this 바인딩에 대해 보다 명확하게 이해할 수 있었고, 우리가 자주 사용하고 있던 메서드에서 자주 사용되었던 콜백함수가 어떤 로직으로 처리가 되고 작동하는지 알 수 있었던 강의였습니다.
비동기와 동기 처리는 특히 백엔드를 배우는 과정에서 중요하게 작용할 요소임을 느끼면서 이번 강의를 마쳤던 것 같습니다.
이전 주차를 확실하게 이해하지 못했다면 4주차 강의를 이해하는데 어려움이 있을것이라고 생각합니다. 복습을 꾸준히 해야겠다고 느꼈습니다.