1. callback 함수
- 다른 함수의 인수로 전달되는 함수입니다. 이러한 함수는 특정 작업이 완료된 후 호출되도록 설계되었습니다. 콜백 함수는 비동기 작업을 처리할 때 자주 사용되며, 이벤트 처리, 타이머 설정, 네트워크 요청 등에 활용됩니다.
- 사용 예제
function a(callback) {
setTimeout(() => {
console.log('A');
callback();
}, 1000);
}
function b() {
console.log('B');
}
a(() => b());
함수 a에서 함수 b를 callback이라는 인수로 받아와 호출하였습니다. 함수 a를 호출할 때도 전달자를 화살표 함수 혹은 일반 함수로 표현하여 함수 b를 호출할 수 있습니다.
function a(callback) {
const str = 'Hello'
setTimeout(() => {
console.log('A');
callback(str);
}, 1000);
}
function b() {
console.log('B');
}
a((event) => {
console.log(event);
b();
});
이처럼 callback 함수에 매개변수도 전달할 수 있습니다.
- 콜백 지옥
이처럼 콜백 함수는 실행 순서를 보장해 줄 수 있지만 콜백함수가 늘어나면 늘어날수록 코드의 복잡성은 커지고 관리하기가 어려워질 수 있습니다.
function a(callback) {
const str = 'Hello';
setTimeout(() => {
console.log('A');
callback();
}, 1000);
}
function b(callback) {
setTimeout(() => {
console.log('B');
callback();
}, 1000);
}
function c(callback) {
setTimeout(() => {
console.log('C');
callback();
}, 1000);
}
function d(callback) {
setTimeout(() => {
console.log('D');
callback();
}, 1000);
}
a(() => b(
() => c(
() => d(
() => console.log('Done')
)
)
)
);
이러한 단점들을 보완하기 위해서 es6부터 새롭게 도입된 Promise 객체를 사용해 보겠습니다.
2. Promise
- 비동기 작업을 처리하는 데 사용되는 객체로, 작업의 성공 또는 실패를 나타내는 값을 처리하는 데 도움을 줍니다. Promise는 미래에 결과가 제공될 것이라는 약속을 나타내며, 콜백 함수의 단점을 보완하여 비동기 코드를 더 직관적이고 가독성 있게 만듭니다.
- 대기 중(Pending): 초기 상태, 작업이 완료되지 않음
- 이행됨(Fulfilled): 작업이 성공적으로 완료됨
- 거부됨(Rejected): 작업이 실패함
- 사용 예제
function a() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('A');
resolve('Hello A');
}, 1000);
});
}
function b() {
console.log('B');
}
async function result() {
const res = await a();
console.log('res: ', res);
b();
}
result();
함수 a에 promise 객체를 생성해서 resolve를 매개변수로 하여 로직 실행 후 특정 부분에서 매개변수가 실행되도록 정해줄 수 있습니다. 함수 result를 비동기로 선언하여 함수 a를 호출할 때 await를 붙여 a가 실행된 후 함수 b가 실행되도록 순서를 지정해 줄 수 있습니다.
- 다중 함수 중복 처리
function a() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('A');
resolve('Hello A');
}, 1000);
});
}
function b() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('B');
resolve('Hello B');
}, 1000);
});
}
function c() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('C');
resolve('Hello C');
}, 1000);
});
}
function d() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('D');
resolve('Hello D');
}, 1000);
});
}
async function result() {
const h1 = await a();
const h2 = await b();
const h3 = await c();
const h4 = await d();
console.log('Done!');
console.log(h1, h2, h3, h4);
}
result();
위와 같이 콜백 함수로 호출 순서를 지정해 줬을 때보다 코드가 좀 더 직관적이고 가독성이 좋아진 것을 알 수 있습니다.
참고 문서:
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
'Front-end > JavaScript' 카테고리의 다른 글
[JavaScript] 비동기 - then, catch, finally (2) | 2024.08.07 |
---|