콜백과 콜백 지옥
콜백으로 순서를 만들고, 그 방식의 한계를 봅니다.
끝난 뒤에 할 일을 넘깁니다
앞 단원에서 맡긴 일의 결과를 바로 아래에서 읽을 수 없다는 것을 봤습니다. 그러면 언제 읽어야 할까요.
끝났을 때 부를 함수를 함께 넘기면 됩니다. 2.6 에서 배운 콜백입니다. 오래 걸리는 일이 끝나면 그쪽에서 이 함수를 불러 줍니다.
끝나면 알려 주기
function loadUser(id, callback) { setTimeout(() => { callback({ id: id, name: "홍길동" }); }, 100); } loadUser(1, user => { console.log(`받았습니다: ${user.name}`); }); console.log("요청했습니다");
loadUser 는 값을 돌려주지 않습니다. 대신
끝났을 때 넘겨받은 함수를 부릅니다. 그래서 결과를 쓰는 코드가 그 함수 안에
들어갑니다.
차례대로 해야 한다면
앞의 결과가 있어야 다음을 할 수 있다면, 콜백 안에서 다시 부릅니다.
function step(name, callback) { setTimeout(() => { console.log(name); callback(); }, 100); } step("첫째", () => { step("둘째", () => { step("셋째", () => { console.log("끝"); }); }); });
동작은 합니다. 다만 단계가 늘어날수록 오른쪽으로 계속 밀립니다. 이것을 콜백 지옥 이라고 부릅니다 — 중첩이 깊어져 어디가 어디인지 알기 어려워지는 모양을 가리키는 말입니다.
오류는 어떻게 알리나
콜백 방식에는 오류를 알릴 자리가 정해져 있지 않습니다. 그래서 첫 인자를 오류로 두는 약속이 널리 쓰였습니다.
function loadUser(id, callback) { setTimeout(() => { if (id <= 0) { callback(new Error("잘못된 번호입니다"), null); return; } callback(null, { id: id, name: "홍길동" }); }, 100); } loadUser(1, (error, user) => { if (error) { console.log("실패:", error.message); return; } console.log("성공:", user.name); }); loadUser(0, (error, user) => { if (error) { console.log("실패:", error.message); return; } console.log("성공:", user.name); });
단계마다 이 검사를 되풀이해야 합니다. 중첩이 깊어지면 오류 처리도 그만큼 흩어져, 한 군데를 빠뜨리기 쉽습니다.
콜백이 나쁜 것은 아닙니다
지금까지 사용해 온 forEach ·
map · addEventListener 도
모두 콜백입니다. 그것들은 아무 문제가 없습니다.
문제가 되는 것은 오래 걸리는 일을 여러 단계로 이어야 할 때입니다. 그 한 가지를 해결하려고 나온 것이 다음 단원의 Promise 입니다.
처음에 자주 걸리는 것
콜백 안의 return 은 그 콜백을 끝낼 뿐입니다.
바깥 함수의 반환값이 아닙니다(2.6).
function load() {
setTimeout(() => { return "값"; }, 100);
}
console.log(load()); // undefined 입니다
첫 인자를 확인하지 않으면 오류가 났는데도 그냥 지나갑니다. 그다음 줄에서 엉뚱한 오류가 나 원인을 찾기 어렵습니다.
오류를 알린 뒤 return 을 빠뜨리면 아래 줄이
이어져 콜백이 두 번 불립니다.
직접 해보기
0.1초 뒤 "준비" 를 출력하고, 그것이 끝나면 다시
0.1초 뒤 "시작" 을 출력하세요.
숫자를 받아 0.1초 뒤 두 배를 돌려주되, 숫자가 아니면 오류를 알리는 함수를 만드세요. 첫 인자를 오류로 두는 약속을 따릅니다.
이 단원의 정리
- 오래 걸리는 일에는 끝났을 때 부를 함수를 함께 넘깁니다.
- 결과를 쓰는 코드가 그 함수 안에 들어갑니다.
- 차례대로 이어야 하면 콜백 안에서 다시 부릅니다 — 깊어지면 콜백 지옥입니다.
- 오류는 첫 인자로 알리는 약속이 널리 쓰였습니다.
- 콜백 자체가 나쁜 것은 아닙니다. 여러 단계를 잇는 자리만 문제입니다.