자바스크립트에서 비동기 처리를 할 때 promise와 callback을 사용한다.
오늘은 이 둘의 차이점에 대해서 알아보려고 한다.
콜백 지옥(Callback hell)
콜백 지옥은 콜백 함수를 익명 함수로 연속해서 사용할 때 발생하는 문제이다. 이벤트 처리나 서버 통신과 같은 비동기적인 작업을 수행할 때 이런 형태가 자주 나타나는데, 가독성이 떨어지고 수정하기가 어렵다.
function async() {
setTimeout((name) => {
console.log(name);
setTimeout((age) => {
console.log(name + " " + age);
setTimeout((sex) => {
console.log(name + " " + age + " " + sex);
}, 500, "M");
},500, 21);
}, 500, "Honggildong");
}
async();
0.5초마다 사람의 정보(이름, 나이, 성별)을 수집하고 출력한다.
>>>>>>>
Honggildong
Honggildong 21
Honggildong 21 M
각 콜백이 사람의 정보를 전달하고 정상적으로 출력하지만 callback이 점점 깊어져 가독성이 떨어지고 코드를 작성하는 데도 어려움이 있다.
이를 해결하는 방법으로는 익명 함수를 직접 분리해주는 방법과 Promise를 사용하는 방법이 있다.
- 코딩 패턴으로 해결(함수 선언)
function selectName(name) {
console.log(name);
setTimeout(selectAge, 500, name + " " + 21);
}
function selectAge(age) {
console.log(age);
setTimeout(selectSex, 500, age + " " + "M");
}
function selectSex(sex) {
console.log(sex);
}
setTimeout(selectName, 500, 'Honggildong');
익명 함수를 모두 기명함수로 선언하여 분리해준 코드이다.
코드의 가독성을 높이고 순서를 따라간다면 코드를 이해하는 것도 개선된다.
그러나 일회성 함수를 전부 선언하는 것은 복잡한 코드에서는 오히려 헷갈릴 수 있다는 단점이 있다.
- Promise로 해결
- Promise 알아보기
function async() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("성공");
},500);
})
}
async().then(res => {
console.log(res)
});
resolve
는 성공했을 때, reject
는 에러가 발생했을 때 첫 번째 인자로 값을 넘길 수 있다.
resolve
는 .then의 첫번째 인자로, reject
는 .catch의 첫 번째 인자로 들어간다.
new 연산자와 함께 호출한 Promise의 인자로 넘겨주는 콜백 함수는 호출할 때 바로 실행되지만 내부에 resolve
또는 reject
함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행되기 전까지는 .then 또는 .catch로 넘어가지 않는다. 따라서 비동기 작업이 완료될 때 resolve
또는 reject
를 호출하는 방법으로 비동기 작업의 동기적 표현이 가능하다.
- promise로 callback지옥 해결하기
function async(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(result);
resolve(result);
});
});
}
async("Honggildong").then(res => {
return async(res + " " + 21);
}).then(res => {
return async(res + " " + "M");
});
위와 같이 코드의 깊이가 깊어지지 않아 가독성이 높아진다.
- Promise + async/await
function selectPerson(param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
});
});
}
const person = async() => {
let personInfo = '';
let _selectPerson = async(param) => {
personInfo += await selectPerson(param) + " ";
};
await _selectPerson('Honggildong');
console.log(personInfo);
await _selectPerson(21);
console.log(personInfo);
await _selectPerson('M');
console.log(personInfo);
}
person();
비동기 작업을 수행하고자 하는 함수 앞에 async
를 표기하고 함수 내부에서 실질적인 비동기 작업이 필요한 때마다 await
를 표기하는 것으로 뒤의 내용을 Promise
로 자동 전환한다. 해당 내용이 resolve
된 이후에 다음으로 진행된다.
'개발 Note > JAVASCIPRT' 카테고리의 다른 글
[JAVASCRIPT] - vue.js로 차트 만들기(2) (0) | 2022.04.24 |
---|---|
[JAVASCRIPT] - vue.js로 차트 만들기(1) (0) | 2022.04.17 |
[JAVASCRIPT] React (0) | 2022.04.01 |
[JAVASCRIPT] JQuery (0) | 2022.03.25 |