
console.log('A');
console.log('B');
//실행결과
A
B

console.log('A');
setTimeout(() => {
console.log('B');
}, 1000);
console.log('C');
//
A
C
(1초 후) B
setTimeout, XMLHttpRequest, fetch, EventListener, WebSocket 등은 대표적인 비동기 함수
과거 콜백함수를 이용하여 비동기 작업을 처리.
콜백 지옥으로 인해 가독성 저하 및 에러 처리 어려움 등으로 유지보수가 힘들다.
login(user, (userInfo) => {
getProfile(userInfo.id, (profile) => {
getPosts(profile.id, (posts) => {
console.log(posts);
});
});
});
이를 개선하기 위해 Promise → async/await 등장
const promise = new Promise((resolve, reject) => {
// 비동기 작업
setTimeout(() => {
resolve('성공!');
}, 1000);
});
promise
.then(result => console.log(result)) // → 성공!
.catch(error => console.error(error))
.finally(() => {
console.log('항상 실행됨');
});
Promise는 비동기 처리가 성공 여부에 따라 다양한 상태(state)를 가진다.
pending: 비동기 처리가 아직 수행되지 않은 상태fulfilled: 비동기 처리가 수행된 상태 (성공)rejected: 비동기 처리가 수행된 상태 (실패)settled: 비동기 처리가 수행된 상태 (성공 또는 실패)Promise 객체 생성
const promise = new Promise((resolve, reject) => {
// 비동기 작업 수행
});
이 시점에서 promise 객체는 pending 상태입니다.
resolve(value)를 호출하면 fulfilled 상태로 전이
reject(reason)을 호출하면 rejected 상태로 전이
비동기 작업 수행 (예: setTimeout, fetch 등)
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('작업 성공');
}, 1000);
});
resolve()나 reject()는 작업이 끝났을 때 “결과”를 전달하는 역할
여기선 1초 뒤 resolve()가 실행되므로 1초 후에 fulfilled 상태가 됨
.then()으로 성공 처리 연결
promise.then(result => {
console.log(result); // → "작업 성공"
});
promise가 fulfilled 상태로 바뀌면, 등록된 .then() 콜백이 호출됨. then 메소드는 Promise를 반환.
result는 resolve()에서 전달한 값
.catch()으로 에러 처리 연결
promise
.then(result => {
console.log(result);
})
.catch(error => {
console.error('에러 발생:', error);
});
reject()가 호출되었거나 .then() 내부에서 에러가 나면 .catch()가 실행됨. catch 메소드는 Promise를 반환.
error는 reject()에서 전달한 값
.finally으로 성공여부 상관없이 항상실행
.catch(error => {
console.error('에러 발생:', error);
})
.finally(() => {
console.log('항상 실행됨');
});
결과에 상관없이 항상 실행됨
finally()는 값을 전달하지 않음 (다음 then()으로는 이전 then()의 결과가 넘어감)
프로미스는 후속 처리 메소드인 then, catch, finally 메소드를 체이닝(chainning)하여 여러 개의 프로미스를 연결하여 사용할 수 있다. 이런 방식을 이용해 콜백 헬을 해결한다.
const promise = new Promise((resolve, reject) => {
console.log('🟡 Promise 시작'); // 즉시 실행됨
setTimeout(() => {
console.log('🟢 비동기 완료 → resolve 호출');
resolve('완료');
}, 1000);
});
console.log('🟠 .then 등록 전');
promise.then(res => {
console.log('🔵 then 실행:', res);
});
console.log('🔴 .then 등록 완료');
//출력
🟡 Promise 시작
🟠 .then 등록 전
🔴 .then 등록 완료
🟢 비동기 완료 → resolve 호출
🔵 then 실행: 완료
async/await는 Promise 기반 비동기 코드를 동기식처럼 읽기 쉽게 작성할 수 있게 해줍니다.
async function 함수명() {
await 비동기_처리_메서드_명();
}
async 함수란?
async function example() {
return 1;
}
example().then(console.log); // 1
await란?
async function delay() {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('1초 후 실행');
}
async await를 이용한 성공 에러처리
await를 통해 then을 사용하지 않고 결과 값을 얻을 수 있고, catch대시 try…catch구문을 이용해 에러처리가 가능하다.
async function f() {
try {
let response = await fetch('http://유효하지-않은-주소');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
에러가 발생하면 제어 흐름이 catch 블록으로 넘어간다. 또한, 여러 줄의 코드를 try로 감쌀 수 있다.
console.log('a');
await time();
console.log('b');
이렇게 하려면 time()이 Promise를 반환해야 await이 효과가 있음.
function time() {
return new Promise(resolve => setTimeout(resolve, 5000));
}
async function run() {
console.log('a');
await time(); // 5초 기다림
console.log('b');
}
run();
//출력
a
(5초 후)
b
출처