
어떤 함수에 인자로 전달되는 함수들
function exercise(callback) {
setTimeout(() => {
console.log('Exercising...');
callback(null, 'Exercise done');
}, 1000);
}
function eat(callback) {
setTimeout(() => {
console.log('Eating healthy food...');
callback(null, 'Meal done');
}, 1000);
}
function sleep(callback) {
setTimeout(() => {
console.log('Sleeping...');
callback(null, 'Sleep done');
}, 1000);
}
// 콜백 지옥 예시
exercise((err, exerciseResult) => {
if (err) {
console.error(err);
} else {
console.log(exerciseResult);
eat((err, mealResult) => {
if (err) {
console.error(err);
} else {
console.log(mealResult);
sleep((err, sleepResult) => {
if (err) {
console.error(err);
} else {
console.log(sleepResult);
console.log('All health activities done!');
}
});
}
});
}
});
resolve() 함수의 인자로는 미래 시점에 얻게될 결과를 넘겨준다reject() 함수의 인자로는 미래 시점에 발생할 예외를 넘겨준다onFulfilled()가 호출된다 (ex) resolve() 호출)onRejected()가 호출된다 (ex) reject() 호출)
Promise 생성자안에 들어가는 콜백 함수를 executor 라고 부른다.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("처리 완료")
}, 5000)
});
console.log(promise); // Pending (대기) 상태
then() : 프로미스가 이행(fulfilled)되었을 때 실행할 콜백 함수를 등록하고, 새로운 프로미스를 반환.
catch() : 프로미스가 거부(rejected)되었을 때 실행할 콜백 함수를 등록하고, 새로운 프로미스를 반환.
finally() : 프로미스가 이행되거나 거부될 때 상관없이 실행할 콜백 함수를 등록하고, 새로운 프로미스를 반환
function exercise() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Exercising...');
resolve('Exercise done');
}, 1000);
});
}
function eat() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Eating healthy food...');
resolve('Meal done');
}, 1000);
});
}
function sleep() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Sleeping...');
resolve('Sleep done');
}, 1000);
});
}
// Promise chaining 예시
exercise()
.then(result => {
console.log(result);
return eat();
})
.then(result => {
console.log(result);
return sleep();
})
.then(result => {
console.log(result);
console.log('All health activities done!');
})
.catch(err => {
console.error(err);
})
.finally(()=>{
console.log("+++")
})
//finally는 이행된 값과 결과에 상관없이 실행되기에 인자를 받지 않는다
// exercise, eat, sleep 함수들은 위의 예제 코드와 동일하다는 가정.
async function performHealthActivities() {
try {
const exerciseResult = await exercise();
console.log(exerciseResult);
const eatResult = await eat();
console.log(eatResult);
const sleepResult = await sleep();
console.log(sleepResult);
console.log('All health activities done!');
} catch (err) {
console.error(err);
}
}
performHealthActivities();
async / await은 무조건 좋음? → ㄴㄴ
async/await은 Promise의 then 체인(가독성 문제)를 어느정도 보완해주었다
하지만 다수의 await의 사용은 성능에 문제를 줄 수 있다. → await 병목현상
await 병목 현상
// exercise, eat, sleep 함수들은 위의 예제 코드와 동일하다는 가정.
async function performHealthActivities() {
try {
const exerciseResult = await exercise();
console.log(exerciseResult);
const eatResult = await eat();
console.log(eatResult);
const sleepResult = await sleep();
console.log(sleepResult);
console.log('All health activities done!');
} catch (err) {
console.error(err);
}
}
performHealthActivities();
//위 코드에서 exercise(), eat(), sleep() 함수가 각각 1초씩 걸린다고 가정하면,
//전체 실행 시간은 3초. 이는 각 작업이 순차적으로 실행되고, 다음 작업이 시작되기 전에 이전 작업이 완료될 때까지 기다리기 때문.
// exercise, eat, sleep 함수들은 위의 예제 코드와 동일하다는 가정.
async function performHealthActivities() {
try {
const results = await Promise.all([exercise(), eat(), sleep()]);
results.forEach(result => console.log(result));
console.log('All health activities done!');
} catch (err) {
console.error(err);
}
}
performHealthActivities();
//하나라도 실패하면 promise는 catch 블록 실행.
//각 작업은 1초가 걸리기에 전체 실행시간도 1초로 줄어들 수 있다.
→ !? 하나라도 실패하면 catch가 실행되는게 걸린다면?
status를 확인할 수 있다fulfilled 상태라면 value를, rejected 상태라면면 reason 속성을 확인할 수 있다async function performHealthActivities() {
try {
const results = await Promise.allSettled([exercise(), eat(), sleep()]);
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log(result.value);
} else if (result.status === 'rejected') {
console.error(result.reason);
//실패에러 발생 시 다시 요청을 보내는 로직 작성 가능.
}
});
console.log('All health activities done!');
} catch (err) {
console.error(err);
}
}
performHealthActivities();