본문 바로가기

프로그래밍 언어/javascript

콜백지옥으로부터의 구출

콜백 지옥은 진짜다. 개발자들은 피할 수 있을 때까지 콜백을 순수한 악마처럼 간주한다. 콜백은 자바스크립트의 유연성에 전혀 도움이 되지 않는다. 표면적으로 콜백은 완벽한 풋 건(foot gun)처럼 보이므로 대체하는 것이 좋다.

좋은 소식으로는 콜백 지옥으로부터 구출될 수 있는 간단한 단계가 있다는 것이다. 당신의 코드에서 콜백들을 제거하는 것은 좋은 다리를 절단하는 것처럼 느껴진다. 콜백 함수는 자바스크립트의 핵심이자 좋은 부분 중 하나이다. 당신이 콜백을 대체할 때 종종 문제들을 교체한다.

친구는 나에게 콜백들은 못생긴 사마귀와 같고, 더 좋은 언어를 공부하기 위한 이유라고 말한다. 정말로 콜백들이 못나게 생겼는가?

자바스크립트에서 콜백을 휘두르면 보상을 받게 된다. 못생긴 사마귀로 변신할 수 있는 콜백 때문에 자바스크립트를 피할 이유는 없다.

사운드 프로그래밍에서 제공하는 콜백에 대해 살펴보자. 솔리드 원칙을 따르고 어디로 우리를 데려갈지 보길 선호한다.

콜백 지옥이란 무엇인가?

나는 당신이 무엇을 생각하는지 알고있다. 콜백 지옥은 무엇이며 왜 신경써야만 하는가? 자바스크립트에서 콜백은 대리인처럼 행동하는 함수이다. 위임자는 미래의 임의의 순간에 실행된다. 자바스크립트에서 위임은 수신 함수가 콜백을 호출할 때 발생한다. 수신 함수는 실행 중에 임의의 지점에서 그렇게 할 수 있다.

간단하게 말하면 콜백은 또 다른 함수에 인자로 넘어가는 함수이다. 콜백은 수신 함수가 실행되는 시점을 결정하기 때문에 바로 실행되지 않는다. 다음은 예제 코드이다.

function receiver(fn) { return fn(); } function callback() { return 'foobar'; } var callbackResponse = receiver(callback); // callbackResponse == 'foobar'

만약 Ajax 요청을 작성해 보았다면 콜백 함수와 마주쳤을 것이다. Ajax 요청과 같은 비동기 코드는 콜백 함수가 실행될 때를 보장할 수 없기 때문에 예제와 같은 접근법을 사용한다.

콜백의 문제점은 또 다른 콜백에 의존하는 비동기 코드를 가진다는 점이다. setTimeout으로 콜백 함수와 함께 비동기 코드를 시뮬레이트해 볼 것이다.

GitHub를 따라가보자. 대부분의 예제 코드들은 레파지토리에서 있다.

운명의 피라미드를 보라!

setTimeout(function (name) { var catList = name + ','; setTimeout(function (name) { catList += name + ','; setTimeout(function (name) { catList += name + ','; setTimeout(function (name) { catList += name + ','; setTimeout(function (name) { catList += name; console.log(catList); }, 1, 'Lion'); }, 1, 'Snow Leopard'); }, 1, 'Lynx'); }, 1, 'Jaguar'); }, 1, 'Panther');

보다시피 setTimeout은 1ms 후에 실행되는 콜백 함수를 가진다. 마지막 파라미터는 콜백에 데이터를 전달한다. 서버로부터 name 파라미터가 반환되는 것을 제외하고는 Ajax 콜과 같다.

이 예제는 이전 아티클이었던 setTimeout 함수의 좋은 예에 있던 것이다.

비동기 코드를 통해서 사나운 고양이 목록(catList)을 모으고 있다. 각각의 콜백은 고양이 한 마리의 이름(ㅜname)을 전달하고 목록에 이름을 추가한다. 성취하고자 하는 방법으로는 합리적이지만, 자바스크립트 함수의 유연성으로 본다면 이 코드는 악몽이다.

익명 함수

당신은 이전 예제에서 익명 함수의 사용을 보았다. 익명 함수는 변수를 할당하거나 다른 함수에 인자로써 전달되는 이름 없는 함수 표현식이다.

익명 함수를 사용하는 것은 몇몇의 프로그래밍 표준에서 추천하지 않는 방식이다. function (name){} 대신 function getCat(name){}으로 함수에 이름을 지정하는 것이 더 좋다. 함수에 이름을 주는 것이 당신의 프로그램을 명확하게 만든다. 이러한 익명 함수들은 입력하기에는 쉽지만 지옥으로 보내버릴 수 있으므로 사용하는 것을 다시 생각해보라.

거대한 콜백을 멈추기 위한 한 가지 간단한 방법으로는 함수 선언을 사용하는 것이다.

setTimeout(getPanther, 1, 'Panther'); var catList = ''; function getPanther(name) { catList = name + ','; setTimeout(getJaguar, 1, 'Jaguar'); } function getJaguar(name) { catList += name + ','; setTimeout(getLynx, 1, 'Lynx'); } function getLynx(name) { catList += name + ','; setTimeout(getSnowLeopard, 1, 'Snow Leopard'); } function getSnowLeopard(name) { catList += name + ','; setTimeout(getLion, 1, 'Lion'); } function getLion(name) { catList += name; console.log(catList); }

레파지토리에서는 찾을 수 없지만, 이 개선 방법은 다음 커밋에 있다.

각 함수는 한 번씩 선언된다. 더 이상 끔찍한 피라미드를 얻지 않는다. 각 함수는 독립되어 있고 하나의 특정 테스크에 집중한다. 각 함수는 변경하기 위해 한 가지 이유만 가지므로, 올바른 방향으로 나아가는 단계이다. 예를 들어, getPanther()는 파라미터로 할당된다. 자바스크립트는 콜백을 생성하는 벙법에 신경쓰지 않는다. 그러나 단점은 무엇인가?

차이점에 대한 자세한 내용은 함수 표현식과 함수 선언 비교에 대한 아티클을 보라.

단점은 각 함수 선언이 더 이상 콜백 안에서 스코프(범위)가 지정되지 않는다는 것이다. 콜백을 클로저로써 사용하는 대신에 각 함수를 외부 스코프에 붙인다. 따라서 왜 catList가 외부 스코프에

A downside, though, is that each function declaration no longer gets scoped inside the callback. Instead of using callbacks as a closure, each function now gets glued to the outer scope. Hence why catList gets declared in the outer scope, as this grants the callbacks access to the list. At times, clobbering the global scope is not an ideal solution. There is also code duplication, as it appends a cat to the list and calls the next callback.

의존성 뒤집기

의존성 뒤집기 원리는 구현 세부 사항이 아닌 코드 추상화를 말한다. 핵심은 큰 문제를 해결하고 의존성을 줄이는 것이다. 이러한 의존성은 부적절한 구현 세부 사항에서 독립적이게 된다.

솔리드 원리 상태 :

이 원리에 따르면,

텍스트의 블롭(blob)이 무엇을 의미하는가? 좋은 소식은 콜백을 파라미터로 할당하는 것이며, 당신은 이미 그렇게 하고 있다! 이 의존성은 계약이 될 것이다. 솔리드 프로그래밍을 하고 있다.

콜백의 자유를 얻는 한 가지 방법은 계약을 만드는 것이다:

fn(catList);

이것은 콜백과 함께 무엇을 계획하는지 정의한다. 이것은 1개의 파라미터, 즉 사나운 고양이 목록(catList)을 추적해야 한다.

이러한 의존성은 매개변수를 통해서 공급받을 수 있다.

function buildFerociousCats(list, returnValue, fn) { setTimeout(function asyncCall(data) { var catList = list === '' ? data : list + ',' + data; fn(catList); }, 1, returnValue); }

다형성 콜백

결론

자바스크립트에서 콜백을 마스터하는 것은 모든 세부 사항을 이해하는 것이다. 나는 당신이 자바스크립트 함수에서 미묘한 변주곡을 보기를 바란다. 콜백 함수는 기본 요소가 부족할 때 오해된다. 자바스크립트 함수가 명백할 때, 솔리드 원리가 따라온다. 솔리드 프로그래밍을 하려면 기본 사항을 철저히 파악해야 한다. 언어의 고유한 융통성은 프로그래머에게 책임감을 준다.

내가 가장 사랑하는 것은 자바스크립트가 좋은 프로그래밍 능력을 키우는 것이다. 모든 세부 사항과 기본 요소의 좋은

이러한 접근법은 바닐라 자바스크립트에서 콜백 함수