개발자공부일기
자바스크립트 기초 문법5 본문
콜백지옥
콜백 지옥(callback hell)이란 비동기 작업이 중첩된 콜백 함수들로 인해 코드의 깊이가 깊어지고 가독성이 떨어지는 현상을 말합니다. 주로 JavaScript에서 비동기 작업(예: 파일 읽기, API 호출, 이벤트 처리 등)을 처리하기 위해 콜백 함수가 반복적으로 사용될 때 발생합니다.
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,
"에스프레소"
);
이런 경우 때문에 자바스크립트에서는 비동기적인 작업을 동기적으로(동기적인 것 처럼 보이도록) 처리해주는 장치를 계속해서 마련해주고 있어요. Promise, Generator(ES6), async/await(ES7)같은 것들이죠
이거 눈으로 따라가며 해석하다 눈운동을 했다.
비동기작업의 동기적 표현
-Promise
new Promise(function (resolve) {
setTimeout(function () {
var name = '에스프레소';
console.log(name);
resolve(name);
}, 500);
}).then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ', 아메리카노';
console.log(name);
resolve(name);
}, 500);
});
}).then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ', 카페모카';
console.log(name);
resolve(name);
}, 500);
});
}).then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ', 카페라떼';
console.log(name);
resolve(name);
}, 500);
});
});
Promise는 비동기 처리에 대해, 처리가 끝나면 알려달라는 ‘약속’이에요.
- new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행돼요.
- 그 내부의 resolve(또는 reject) 함수를 호출하는 구문이 있을 경우 resolve(또는 reject) 둘 중 하나가 실행되기 전까지는 다음(then), 오류(catch)로 넘어가지 않아요.
- 따라서, 비동기작업이 완료될 때 비로소 resolve, reject 호출해요.
- Generator
*가 붙은 함수가 제너레이터 함수입니다. 제너레이터 함수는 실행하면, Iterator 객체가 반환(next()를 가지고 있음)돼요.
iterator 은 객체는 next 메서드로 순환 할 수 있는 객체구요. next 메서드 호출 시, Generator 함수 내부에서 가장 먼저 등장하는 yield에서 stop 이후 다시 next 메서드를 호출하면 멈췄던 부분 -> 그 다음의 yield까지 실행 후 stop
즉, 비동기 작업이 완료되는 시점마다 next 메서드를 호출해주면 Generator 함수 내부소스가 위 -> 아래 순차적으로 진행돼요
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ', ' + name : name);
}, 500);
};
var coffeeGenerator = function* () {
var espresso = yield addCoffee('', '에스프레소');
console.log(espresso);
var americano = yield addCoffee(espresso, '아메리카노');
console.log(americano);
var mocha = yield addCoffee(americano, '카페모카');
console.log(mocha);
var latte = yield addCoffee(mocha, '카페라떼');
console.log(latte);
};
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
- Promise + Async/await
ES2017에서 새롭게 추가된 async/await 문을 이용했어요. 비동기 작업을 수행코자 하는 함수 앞에 async 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await를 붙여주면 된답니다.
var addCoffee = function (name) {
return new Promise(function (resolve) {
setTimeout(function(){
resolve(name);
}, 500);
});
};
var coffeeMaker = async function () {
var coffeeList = '';
var _addCoffee = async function (name) {
coffeeList += (coffeeList ? ', ' : '') + await addCoffee(name);
};
await _addCoffee('에스프레소');
console.log(coffeeList);
await _addCoffee('아메리카노');
console.log(coffeeList);
await _addCoffee('카페모카');
console.log(coffeeList);
await _addCoffee('카페라떼');
console.log(coffeeList);
};
coffeeMaker();
코드들을 눈으로 다 따라다니며 해석해보려 했는데 익숙치 않은건지 이해가 안된건지 해석하다 자꾸 길을 잃었다.
이정도 길이에 길을 잃으면 안되는데..? 예시들을 좀 자주 살펴보며 눈에 익혀야겠다. this의 행방이랑 콜백함수에 대해 자꾸 헷갈렸는데 하루종일 찾아보다보니 눈에 익었다. 그리고 Promise라던가 setTimeout같은 함수들의 형태를 몰라서 더 헷갈렸던거 같다. 처음 보는 함수가 생기면 MDN에 쳐보고 오자.
'TIL(Today I Learned)' 카테고리의 다른 글
개인과제 1일차(트러블 슈팅) (0) | 2024.11.11 |
---|---|
자바스크립트 기초 문법6 (0) | 2024.11.08 |
자바스크립트 기초 문법4 (0) | 2024.11.06 |
자바스크립트 기초 문법3 (0) | 2024.11.05 |
자바스크립트 기초 문법2 (0) | 2024.11.04 |