https://joseph0926.tistory.com/25
이 주제에 대해서는 위의 링크에서 자세히 알아본 적이 있다.
그럼에도 글을 하나 더 쓰는 이유는,
프로미스에 대한 설명이 없는 것과
위 글에서 설명이 부족한 부분의 보충이다.
이 글에서 알아볼 것
- 콜백 지옥 (Callback Hell) 이란?
- 프로미스 (Promise) 란?
- async / await 키워드 보충
1. 콜백 지옥 (Callback Hell) 이란?
원래 글에서 설명했듯이,
콜백함수란 async code를 작성할때 필요한 코드로, 자바스크립트와 브라우저의 의사소통 수단으로 사용되는 함수다.
또한, 콜백 함수는 중첩이 가능하다고도 말했었다.
하지만 이런 콜백 함수에는 치명적인 단점이 존재한다.
예를들어보자
const dummyFn = () => {
console.log("add messi"); //1
console.log("messi start!"); //2
setTimeout(() => {
console.log("messi done..."); //4
console.log("pedri start!"); //5
setTimeout(() => {
console.log("pedri done.."); //7
console.log("dejong start!"); //8
setTimeout(() => {
console.log("dejong done..."); //9
}, 2000);
}, 5000);
console.log("add dejong"); //6
}, 10000);
};
dummyFn();
console.log("add pedri"); //3
- 각 선수별로 add -> start -> done 단계를 꼭 거쳐야하고 이를 무조건 setTimeout()을 이용해야한다고 가정하자.
- .그러면 위처럼 코드를 작성할 수 있는데, 코드를 보기만 하여도 문제점이 뭔지 알수있다.
- 콜백이 콜백을 감싸고 그 콜백이 또 다른 콜백을 감싸고…이러한 callback hell이 발생한다.
- 이는 코드의 가독성을 심각하게 낮추는 문제가 존재한다.
- 이러한 문제를 해결해주는 것이 프로미스(Promise)다.
2. 프로미스(Promise)란?
- 이름 그대로 어떤 작업에 대해서 약속을 하는것이다.
- 약속을 보류(pending)하거나, 해결(resolved)하거나, 거부(rejected)한다.
- 프로미스 사용법
- 프로미스 생성
- const promise = new Promise();
- Promise() 생성자에서는 콜백함수를 받는다
- 콜백 함수 전달
- new Promise((resolve, reject) ⇒ {})
- 콜백 함수의 매개변수에는 두개의 함수를 넣을수있다.
- 해결되었을때(resolve), 거부되었을때(reject)
- 프로미스 생성
const promise = new Promise((resolve, reject) => {
let isValid = true;
if (isValid) {
resolve("성공!");
} else {
reject("실패ㅠ");
}
});
3. 성공하였을때와 실패하였을때 처리를 해줘야 한다.
- 성공 → resolve → then 블럭
- promise.then((data) => {})
- then은 콜백함수를 인자로 받고 그 콜백함수의 인자로 프로미스의 값에 접근할수있다.(위의 코드에서는 “성공!”)
- 실패 → reject → catch 블럭
- then과 마찬가지로 catch블럭은 콜백함수를 인자로 받고 그 콜백함수의 인자로 프로미스의 값에 접근할수있다.(위의 코드에서는 “실패ㅠ”)
이런식으로 사용할 수 있다.
그러면 프로미스를 활용한 예제 코드를 보고 위의 callback hell에 비해 나아졌는지 확인해보자
btn.addEventListener("click", () => {
addColor(1000, messi, "red")
.then((data) => {
console.log(data);
addColor(2000, pedri, "green");
})
.then((data) => {
console.log(data);
addColor(5000, dejong, "blue");
})
.catch((err) => {
console.log(err);
});
});
const addColor = (time, element, color) => {
const promise = new Promise((resolve, reject) => {
if (element) {
setTimeout(() => {
element.style.color = color;
resolve();
}, time);
} else {
reject(new Error("Error!!!!!!"));
}
});
return promise;
};
기존의 콜백함수만 이용한 코드라면,
addColor가 중첩되어있는 저 부분이 매우 복잡하였을 것이다.
반면, 프로미스를 활용하니 then을 기준으로 나눠져있어 가독성이 훨씬 좋아졌다.
- 근데 만약 위의 코드 두번째 then에서 오류가 발생하면 세번째 then은 어떻게 될까?
- 실행된다..왜냐하면 기본적으로 프로미스는 비동기 코드이기때문이다.
- 이것을 원할수도있으나, 앞에서 오류가 발생하면 멈추고싶을때도 존재한다
- 이때 async / await를 사용하자
3. async / await 보충
async / await에 대한 설명은 앞 글에서 충분히 살펴보았으니,
위의 프로미스 예제 코드만 async / await 코드로 바꿔복고 글을 마무리하겠다.
btn.addEventListener("click", async () => {
displayColor().then((data) => {
console.log(data);
});
});
const displayColor = async () => {
try {
await addColor(1000, messi, "red");
await addColor(2000, pedri, "green");
await addColor(1000, dejong, "blue");
} catch (error) {
console.log(error);
}
};
const addColor = (time, element, color) => {
const promise = new Promise((resolve, reject) => {
if (element) {
setTimeout(() => {
element.style.color = color;
resolve("성공!");
}, time);
} else {
reject(new Error("Error!!!!!!"));
}
});
return promise;
};
여기서는 두번째 addColor에서 오류가 발생하면 세번째 addColor는 무시되고 catch 블럭으로 이동한다.
'OLD > Javascript' 카테고리의 다른 글
[Javascript] this 키워드 알아보기 (0) | 2024.03.24 |
---|---|
[Javascript] 자바스크립트 프로토타입(Prototype) (0) | 2023.03.01 |
[Javascript] 자바스크립트로 브라우저 저장소 이용하기 (LocalStorage, Cookies, indexedDB) (0) | 2023.02.27 |
[Javascript] 자바스크립트 모듈 (0) | 2023.02.26 |
[Javascript] 자바스크립트 HTTP 통신 (XMLHttpRequest vs fetch() vs axios ...) (0) | 2023.02.26 |