자바스크립트에서 비동기 호출은 이해하기가 쉽지 않고 막상 코드를 작성해도 왠지 개운치가 않을 경우가 많다. 이번 포스트에서는 ES6에 추가된 Promise라는 객체를 이용해서 비동기 작업을 처리하는 방법에 대해 알아보자.
비 동기 작업과 callback hell
동기(synchronous) 작업과 비동기(asynchronous) 작업
동기 작업은 코드를 한 줄 한줄 실행하면서 이전 코드의 동작 결과를 받은 후 다음 코드가 실행되는 구조이다. 반면 비동기 작업은 코드를 실행하다가 이전 코드의 동작 결과를 받지 않고 바로 다음 코드를 실행하는 구조이다.
간단한 비동기 작업으로 setTimeout 함수를 사용해보자.
let num = 0;
setTimeout(() => {
console.log(`작업 진행: ${num++} 번째 작업 진행 ..`);
}, 1000);
console.log(`작업 결과 num: ${num}`);
위의 코드에서 setTimeout은 1초 후에 처리될 작업(callback)을 비 동기로 만들어서 던져버리고 바로 "작업 결과~~"가 콘솔에 출력된다. 그리고 언젠가 "작업 진행~~~"의 내용이 출력된다. 최초의 의도가 비동기 작업이 끝난 후 결과를 출력하고 싶었다면 낭패다.
만약 비동기 작업 후 결과를 받아서 처리하려면 다음과 같이 callback 내에 코드가 작성되어야 한다.
let num = 0;
setTimeout(() => {
console.log(`작업 진행: ${num++} 번째 작업 진행 ..`);
console.log(`작업 결과 num: ${num}`);
}, 1000);
Callback Hell
문제는 1초 후에 또 1초 후에, 또 1초 후에 이런식으로 계속 callback 내에서 다른 callback을 불러야 하는 경우가 발생한다.
setTimeout(() => {
console.log(`작업 진행: ${num++} 번째 작업 진행 ..`);
console.log(`작업 결과 num: ${num}`);
setTimeout(() => {
console.log(`작업 진행: ${num++} 번째 작업 진행 ..`);
console.log(`작업 결과 num: ${num}`);
setTimeout(() => {
console.log(`작업 진행: ${num++} 번째 작업 진행 ..`);
console.log(`작업 결과 num: ${num}`);
}, 1000);
}, 1000);
}, 1000);
물론 동작은 잘 하지만 이런 코드가 심각해지면 코드를 쳐다보는 것만으로도 숨이 턱턱 막히게 되고 어디서 잘못되었는지 추적하기란 하늘의 별따기가 될 것이다. 이를 callback hell이라 한다.