참고
콜백함수(CallBack)
NOTE
콜백함수는 다른 함수에 인자로 전달되는 함수를 뜻하며, 어떤 이벤트가 발생했거나 특정 작업이 완료된 후에 호출됩니다.
콜백 함수를 사용하는 것은 비동기적인 작업들을 관리하는데 아주 유용한 방법입니다. 특히 웹 개발에서 비동기 작업(데이터 가져오기, 외부 스크립트 로드)이 빈번하게 발생하는데 이러한 작업들은 완료되는 데 시간이 걸리기 때문에 콜백 함수로 설정하여 사용합니다.
function func(callback) {
callback();
}
function callback() {
console.log("callback이다");
}
func(callback);
JavaScript
복사
콜백의 형태
// 5초가 지난뒤에 함수실행
function f(){
console.log("After timeout: " + new Date());
}
setTimeout(f, 5*1000);
JavaScript
복사
setTimeOut 예제 (특정시간 이후 콜백호출)
// 5초 간격으로 콜백함수 실행
const start = new Date();
let i = 0;
const intervalid = setInterval(function () {
let now = new Date();
// 50초뒤에 멈춘다.
if (now.getMinutes() !== start.getMinutes() || ++i > 10) return clearInterval(intervalid);
console.log(`${i}:${now}`);
}, 5 * 1000);
JavaScript
복사
setInterval 예제 (정해진 주기마다 콜백호출)
콜백함수 예시
•
setTimeout : 콜백 함수를 한번만 실행하고 멈춥니다.
•
setInterval : 콜백을 정해진 주기마다 호출하여 clearInterval을 사용할 떄 까지 진행합니다.
콜백 함수의 특징
NOTE
콜백 함수 장점
•
비동기 작업이 완료된 이후에 특정 코드를 실행할 수 있게 해주며 이는 웹애플리케이션의 반응성을 높이는데
•
자바스크립트에서 비동기 처리는 실행 결과를 기다리지 안혹 다음 코드를 실행하는 것을 말합니다. 예를들어 웹 API, 파일 읽기/쓰기와 같은 작업을 비동기적으로 처리할 수 있습니다.
콜백 헬
콜백 함수를 너무 많이 중첩하게 되면, 코드의 가독성과 유지보수가 떨어지는 경우를 설명합니다.
step1(function (value1) {
step2(function (value2) {
step3(function (value3) {
step4(function (value4) {
step5(function (value5) {
step6(function (value6) {
// Do something with value6
});
});
});
});
});
});
JavaScript
복사
멸망의 피라미드라고 부른다.
•
이렇게 비동기적인 코드가 늘어날수록 버그가 생기고 쉬운 코드 작성이 어려워집니다.
프라미스(Promise)
NOTE
promise는 자바스크립트 비동기 처리에 사용되는 객체이며 비동기 작업의 성공과 실패를 나타내는 값을 가집니다.
state, result에는 개발자가 직접 접근할 수 없습니다.
let promise = new Promise(function(resolve, reject) {
// 비동기 작업을 수행합니다.
if (/* 작업 성공 */) {
resolve(value); // 작업이 성공적으로 완료되면 resolve 호출 (fulfilled 상태)
} else {
reject(error); // 작업이 실패하면 reject 호출 (rejected 상태)
}
});
JavaScript
복사
promise 생성
프라미스 사용, 체이닝
NOTE
promise
.then(function(result) { // 성공 시 결과 값 처리
console.log(result);
})
.catch(function(error) { // 실패 시 오류 처리
console.error(error);
})
.finally(function() { // 항상 실행
console.log('Promise가 처리되었습니다.');
});
JavaScript
복사
비동기 작업 결과에 따른 후속처리
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); // 1초뒤 1을 반환
})
.then(function(result) { // 성공하면 2배
console.log(result); // 1
return result * 2;
})
.then(function(result) { // // 성공하면 2배
console.log(result); // 2
return result * 2;
})
.then(function(result) { // // 성공하면 2배
console.log(result); // 4
return result * 2;
});
JavaScript
복사
여러개의 then()을 통해 체이닝이 가능하다. (then은 새로운 promise를 반환한다.)
프라미스 API
NOTE
promise 클래스에는 5가지 정적 메서드가 있습니다.
1.
Promise.all(promises) : 모든 프라미스가 이행될 때까지 기다렸다가 그 결괏값을 담은 배열을 반환합니다. 주어진 프라미스 중 하나라도 실패하면 Promise.all는 거부되고, 나머지 프라미스의 결과는 무시됩니다.
2.
Promise.allSettled(promises): 최근에 추가된 메서드로 모든 프라미스가 처리될 때까지 기다렸다가 그 결과(객체)를 담은 배열을 반환합니다. 객체엔 다음과 같은 정보가 담깁니다.
•
status: "fulfilled" 또는 "rejected"
•
value(프라미스가 성공한 경우) 또는 reason(프라미스가 실패한 경우)
3.
Promise.race(promises): 가장 먼저 처리된 프라미스의 결과 또는 에러를 담은 프라미스를 반환합니다.
4.
Promise.resolve(value): 주어진 값을 사용해 이행 상태의 프라미스를 만듭니다.
5.
Promise.reject(error): 주어진 에러를 사용해 거부 상태의 프라미스를 만듭니다.
async와 await 함수
NOTE
async와 await를 사용하면 앞서 배웠던 promise를 좀 더 편하게 사용할 수 있어 비동기 코드의 복잡성을 크게 줄일 수 있습니다.
async 키워드는 함수 앞에 위치하며, 무조건 프라미스를 반환하게 해줍니다. 또한 내부에서 발생한 예외는 Promise.reject()로 감싸서 거부된 프라미스로 반환됩니다.
async function asyncFunction() {
return "성공";
}
asyncFunction().then(alert); // "성공"
JavaScript
복사
await 연산자는 async 함수 내부에서만 사용할 수 있으며 await는 프라미스가 이행될 때까지 함수 실행을 일시 정지하고 프라미스의 결과값을 반환합니다.
async function fetchText() {
let response = await fetch('https://example.com');
return response.text();
}
fetchText().then(text => console.log(text));
JavaScript
복사
async - await
function fetchText() {
return fetch('https://example.com') // 첫 번째 프라미스 반환
// then => await로 대처가능!
.then(response => {
return response.text(); // 두 번째 프라미스 반환
});
}
fetchText().then(text => console.log(text));
JavaScript
복사
원본 코드
async function fetchTextWithTryCatch() {
try {
let response = await fetch('https://example.com');
let text = await response.text();
return text;
} catch (error) {
console.error('fetch failed: ', error);
}
}
JavaScript
복사
예외 처리
•
await는 프라미스가 거부될 경우 예외를 발생시킵니다. 이 예외는 try..cactch 문을 사용하여 처리할 수 있습니다.
•
await를 사용하면 프라미스의 .then 체이닝 대신 비도익 작업 결과를 기다리는 동안 실행 흐름을 멈출 수 있습니다.