비동기 연산의 상태를 나타내는 객체이다!
비동기 프로그래밍을 보다 간결하게 표기 하기 위해 ES6에서 등장한 문법이다!
비동기란?
https://velog.io/@twoone14/동기비동기-블로킹논블로킹
위 포스팅에서 자세히 알아 볼수 있습니다.
(new Promise((resolve, reject) => {
if(isSuccess)
resolve("여기가 맛집인가?"); // 비동기 작업의 결과를 resolve함수를 호출하며 넘긴다.
else
reject(new Error("맛집 아닌듯.."));
}))
// then 체이닝으로 비동기 작업이 끝났을때 할 작업을 넘겨 줄수 있다.
// resolve로 넘긴 데이터가 then의 콜백인자로 넘어온다.
.then((result) => {
console.log(result); // "여기가 맛집인가?"
})
// catch 체이닝으로 비동기 작업이 거절, reject, 에러 가 났을때 작업을 넘겨 줄수 있다.
// reject로 넘겨준 에러가 catch 의 콜백 인자로 넘어오게 된다.
.catch((e) => {
console.error(e); // Error "맛집 아닌듯.."
});
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("3초 끝~");
}, 3000) //3초 대기
}).then((message)=> {
console.log(message); // 3초뒤 "3초 끝~" 가 콘솔에 출력됨!
})
비동기 작업의 상태에 따라 Promise 객체는 아래와 같은 상태를 가진다.




Promise 객체가 나오기 전에는 콜백 ( 나중에 호출될 함수 ) 를 인자로 넘겨주어 가독성이 심하게 좋지 않았음
예시 )
비동기 함수 정의
const aFun = (successCallback, errorCallback) => {
const isSuccess = true | false // 어떤 비동기 작업
if (isSuccess) {
successCallback();
} else {
errorCallback();
};
}
비동기 함수를 호출하는 곳
aFun(() => {
console.log("여기 성공했음!");
} , () => {
console.log("여긴 실패!");
})
예시는 callback을 하나만 중첩 시켰지만 비동기 함수를 2번, 3번 씩 중첩하여 호출하게 된다면 아래와 같은 모습이 만들어 질것이다.
aFun1(() => {
aFun2(() => {
aFun3(()=> {
console.log("여긴 어디...");
})
})
});
이렇게 콜백이 많이 호출 되며 들여쓰기가 많아 가독성이 떨어지는 상태를 콜백 지옥 (Callback Hell) 이라고 부른다.
Promise 의 완료를 기다리기 위한 문법이다.
아래와 같이 Promise 를 await 로 기다려 보자

Promise 객체가 찍히는게 아니라 resolve 된 결과 값인 ‘abc’ 가 콘솔에 찍히게 된다.
콘솔 전역 환경에서는 await 문법이 전역에서 사용가능하지만 함수 안에서는 async 키워드와 함께 같이 사용해야만 한다.

await is only valid in async functions and the top level bodies of modules
// await은 비동기 함수와 모듈의 최상위 바디에서만 유효합니다.
async await 에서 에러 핸들링은 try-catch 문에서 사용해야한다.
// 에러 핸들링이 안되는 코드
let a = async () => {
let result = await fetch('무효한 url'); // 에러가 나도 잡을 reject가 없기에 잡을수 없음
}
// try-catch 로 에러 핸들링을 하는 코드
let a = async () => {
try {
let result = await fetch('무효한 url');
} catch (e) {
console.error(e); // 에러 발생시 catch 블락의 코드가 실행됨!
}
}
여러개의 비동기 함수를 호출할때에는 await를 신중히 사용하자
아래와 같은 비동기 작업을 하는 delay 함수를 만들었다 가정하자.
const delay = (millisec) => {
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve();
}, millisec)
})
};
await 를 이용해 위 delay함수를 3번 호출한다면 어떻게 될까
const a = async () => {
await delay(1000) // 1초대기
await delay(2000) // 2초대기
await delay(3000) // 3초대기
console.log("6초나 기다려야함;;"); // 6초를 기다려야 아래 코드가 실행된다.
};
delay라 이름을 지어놔서 6초를 기다리는게 당연한 것처럼 보이지만 delay가 아니라 api 호출 함수였다면…?
병렬적으로 api 호출을 해야하기에 문제가 생긴다.
아래와 같이 Promise.all 또는 Promise.allSettled 를 이용하여 병렬적으로 모든 Promise를 기다리자
await Promise.all([delay(1000), delay(2000), delay(3000)]
// 가장 오래기다리는 3초를 기다린뒤 아래 코드가 실행된다.
참고자료
https://www.youtube.com/watch?v=li7FzDHYZpc&pp=ygURcHJvbWlzZSBhc3ljIGFhaXQ=
https://www.youtube.com/watch?v=iUGLyhbwYkU&pp=ygUZcHJvbWlzZSBhc3ljIGF3YWl0IOyEpOuqhQ==