async / await 문법은 ES8에 해당하는 문법으로서, Promise를 더욱 쉽게 사용할 수 있게 해준다.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function process() {
console.log('안녕하세요!');
await sleep(1000); // 1초 쉬고
console.log('반갑습니다!');
}
process();
async/await 문법을 사용할 때에는, 함수를 선언할때 함수의 앞 부분에 async
키워드를 붙여준다. 그리고 Promise 앞부분에 await
를 넣어주면 해당 프로미스가 끝날 때까지 기다렸다가 다음 작업을 수행할 수 있다.
위 코드에서는 sleep
이라는 함수를 만들어서 파라미터로 넣어준 시간만큼 기다리는 Promise를 만들고, 이를 process
함수에서 사용해주었다.
함수에서 async
를 사용하면, 해당 함수는 결과값으로 Promise를 반환하게 된다.
따라서 다음과 같이 코드를 작성할 수 있다.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function process() {
console.log('안녕하세요!');
await sleep(1000); // 1초 쉬고
console.log('반갑습니다!');
}
process().then(() => {
console.log('작업이 끝났어요!');
});
async
함수에서 에러를 발생 시킬 때에는 throw
를 사용하고, 에러를 잡아낼 때에는 try/catch 문을 사용한다.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function makeError() {
await sleep(1000);
const error = new Error();
throw error
}
async function process() {
try {
await makeError();
} catch (e) {
console.error(e);
}
}
process();
서로 다르게 호출시간이 지정된 콜백함수를 동시에 작업 시작하고 싶다면, 다음과 같이 Promise.all
을 사용해야 한다.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const getDog = async () => {
await sleep(1000);
return '멍멍이';
};
const getRabbit = async () => {
await sleep(500);
return '토끼';
};
const getTurtle = async () => {
await sleep(3000);
return '거북이';
};
async function process() {
const results = await Promise.all([getDog(), getRabbit(), getTurtle()])
console.log(results);
}
process();
여기서 배열 비구조화 할당 문법을 사용하면 각 결과값을 따로 따로 추출해서 조회할 수 있다.
//async function process() {
// const results = await Promise.all([getDog(), getRabbit(), getTurtle()])
// console.log(results);
//}
//process();
async function process() {
const [dog, rabbit, turtle] = await Promise.all([
getDog(),
getRabbit(),
getTurtle()
]);
console.log(dog);
console.log(rabbit);
console.log(turtle);
}
process();
Promise.all
을 사용할 때에는, 등록한 프로미스 중 하나라도 실패하면 모든게 실패한 것으로 간주한다.
반면 Promise.race
는 여러개의 프로미스를 등록해서 실행했을 때 가장 빨리 끝난 것 하나만의 결과값을 가져온다.
async function process() {
const first = await Promise.race([
getDog(),
getRabbit(),
getTurtle()
]);
console.log(first);
}
process();
Promise.race
의 경우엔 가장 다른 Promise가 먼저 성공하기 전에 가장 먼저 끝난 Promise가 실패하면 이를 실패로 간주한다. 따라서, 현재 위 코드에서 getRabbit에서 에러를 발생시킨다면 에러를 잡아낼 수 있지만, getTurtle이나 getDog에서 발생한 에러는 무시된다.