js에서 promise는 비동기 작업의 최종완료 또는 실패와 그 결과 값을 나타내는 객체이다.
쉽게 말해, "지금 당장은 데이터를 줄 수 없지만, 작업이 끝나면 성공했는지 실패했는지 알려주고 결과값도 줄게" 라는 약속을 담은 객체라고 이해하면 됨.

js에서 네트워크 요청(fetch),파일읽기,타이머,DB I/O 같은 작업은 즉시 결과가 안나옴.
그래서 "끝나면 이거 해줘"를 깔끔하게 표현하려고 promise를 씀.
- 콜백만 쓰면: 중첩이 깊어지면서 가독성/에러처리 힘들어짐(일명 callback hell)
- promise를 쓰면: then/catch/finally로 흐름을 일렬로 만들 수 있고, 에러처리도 한군데로 모으기 쉬움
promise는 항상 아래 중 하나의 상태를 가짐.
1. pending: 진행 중(아직 결정 안남)
2. fulfilled: 성공(resolve로 결정)
3. rejected: 실패(reject로 결정)
new Promise()생성자를 사용하며, 두개의 매개변수를 가진 콜백함수(Executor)를 넣는다.
const myPromise = new Promise((resolve,reject) => {
//비동기 작업을 수행하는 척 (1초대기)
const success = true;
setTimeout(()=>{
if(success) {
//성공 시 resoleve 호출 (값을 전달)
resolve("성공했습니다!");
}else{
//실패 시 reject 호출 (에러 전달)
reject(new Error("실패했습니다..."));
}
},1000);
});
resolve : 작업이 성공적으로 끝났을때 호출reject : 작업 중 에러가 발생했을 때 호출만들어진 Promise 객체는 .then(), .catch(), .finally() 메서드를 통해 결과를 처리합니다.
myPromise
.then((result)=>{
//resolve가 호출되면 실행됨
console.log(result); //출력: "성공했습니다!"
})
.catch((error)=>{
//reject가 호출되면 실행됨
console.error(error); //출력: Error 객체
})
.finally(()=>{
//성공/실패 여부와 상관없이 무조건 마지막에 실행됨
console.log("작업이 끝났습니다");
});
Promise의 강력한 점은 여러 비동기 작업을 순착적으로 연결할수 있다는 것임.
.then()메서드는 새로운 Promise를 반환하므로 계속 이어 붙일 수 있다.
function fetchNumber() {
return new Promise((resolve) => resolve(1));
}
fetchNumber()
.then(num => {
console.log(num); // 1
return num * 2; // 다음 .then으로 2를 전달
})
.then(num => {
console.log(num); // 2
return num * 3; // 다음 .then으로 6을 전달
})
.then(num => {
console.log(num); // 6
});
async와 await는 복잡한 비동기 처리 코드를 마치 동기식 코드(위에서 아래로 순서대로 실행되는 코드)처럼 직관적이고 읽기 쉽게 작성할 수 있도록 돕는 자바스크립트 문법이다.
기존의 Promise 객체에 .then()과 .catch()를 계속 연결하다 보면 코드가 길어지고 복잡해지는 단점이 있었는데, 이를 깔끔하게 해결해 준다.
함수 선언 앞에 async 키워드를 붙여서 사용한다.
async가 붙은 함수는 결과값이 무엇이든 항상 Promise 객체를 반환한다.
함수 안에서 단순한 문자열이나 숫자를 반환(return)하더라도, 자바스크립트가 알아서 그 값을 이행(Fulfilled) 상태의 Promise로 감싸서 반환해 준다.
await 키워드는 반드시 async 함수 내부에서만 사용할 수 있다.
비동기 작업(Promise를 반환하는 함수) 앞에 await를 붙이면, 해당 Promise가 처리될 때까지(성공하든 실패하든) 잠시 코드 실행을 멈추고 기다린다.
작업이 성공적으로 끝나면, Promise에서 반환된 결과값을 추출하여 전달한다. 이 덕분에 콜백 함수(.then()) 없이도 결과값을 바로 변수에 담을 수 있다.
1) 기존 Promise (.then()) 방식
function getUser() {
// fetchUser()가 비동기 함수라고 가정한다.
fetchUser(1)
.then((user) => {
console.log("유저 이름:", user.name);
});
}
2) async / await 방식
async function getUser() {
// fetchUser() 작업이 끝날 때까지 기다렸다가, 결과가 나오면 변수에 담는다.
const user = await fetchUser(1);
console.log("유저 이름:", user.name);
}
코드가 위에서 아래로 자연스럽게 흐르기 때문에 가독성이 훨씬 뛰어나다.
기존 방식에서는 .catch()를 사용해 에러를 처리했지만, async/await에서는 자바스크립트의 표준 에러 처리 방식인 try...catch 문을 그대로 사용할 수 있다.
async function printUserInfo(userId) {
try {
// 성공할 것으로 예상되는 코드를 작성한다.
const user = await fetchUser(userId);
console.log("조회 성공:", user.name);
} catch (error) {
// await 하고 있는 Promise가 실패(Rejected)하면 즉시 이 곳으로 넘어온다.
console.error("에러 발생:", error.message);
}
}
결론적으로 async/await는 기존의 Promise를 없애고 새로 나온 것이 아니라, Promise를 더 쉽고 편하게 사용하기 위해 껍데기만 포장한 문법(Syntactic Sugar)이다. 내부적으로는 여전히 Promise를 기반으로 동작한다.