velopert님의 모던 자바스크립트 강의자료를 참고하여 작성했습니다.
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().then(() => {
console.log('작업이 끝났어요!');
});
일단 함수를 선언할 때 함수 앞부분에 async
키워드를 붙인다. 그리고 Promise 앞부분에 await
을 넣어주면 해당 프로미스가 끝날때 까지 기다렸다가 다음작업을 수행한다.
위 코드에서는 sleep이라는 함수를 만들어서 파라미터로 넣어준 시간만큼 기다리는 Promise를 만들고 이를 process 함수에서 사용했다.
함수에서 async
를 사용하면, 해당 함수는 결과값으로 Promise를 반환하게 된다.
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();
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 dog = await getDog();
console.log(dog);
const rabbit = await getRabbit();
console.log(rabbit);
const turtle = await getTurtle();
console.log(turtle);
}
process();
비동기 함수를 실행하면 프로미스함수에 전달된 시간만큼 기다렸다가 값을 반환하는데 위에서 부터 순차적으로 수행되기 때문에 총 수행시간은 4.5초가 걸린다.
만약 순차적으로 실행되는게아니라 한꺼번에 실행하고 싶다면 Promise.all
을 하면된다.
async function process() {
const results = await Promise.all([getDog(), getRabbit(), getTurtle()]);
console.log(results);
}
//비구조화 문법을사용하면 각각의 값으로 분리해서 출력할 수 있다.
async function process() {
const [dog, rabbit, turtle] = await Promise.all([
getDog(),
getRabbit(),
getTurtle()
]);
console.log(dog);
console.log(rabbit);
console.log(turtle);
}
Promise.all
를 사용 할 때에는, 등록한 프로미스 중 하나라도 실패하면, 모든게 실패 한 것으로 간주한다.
여러개의 프로미스를 등록해서 실행했을 때 가장 빨리 끝난것 하나만의 결과값을 가져온다.
async function process() {
const first = await Promise.race([
getDog(),
getRabbit(),
getTurtle()
]);
console.log(first);
}
process(); // 토끼
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
}
p(1000).then(ms => {
console.log(`${ms}ms 후에 실행된다.`);
});
const ms = await p(1000);
console.log(`${ms} ms 후에 실행된다.`);
위 방식은 오류가 발생한다. 그 이유는 await는 async 함수안에서만 사용이 가능하기 때문이다. await는 resolve로 넘어온 인자를 리턴한다. await의 장점은 순차실행이 직관적이라는 점이다.
(async function main() {
const ms = await p(1000);
console.log(`${ms} ms 후에 실행된다.`);
})();
try-catch를 사용해서 처리한다.
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('reason');
}, ms);
});
}
(async function main() {
try {
const ms = await p(1000);
} catch (error) {
console.log(error);
}
})();
async function에서 return되는 값은 Promise.resolve 함수로 감싸서 리턴된다.
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(ms);
//reject(new Error('reason');
}, ms);
});
}
async function asyncP() {
const ms = await p(1000);
return 'Mark: ' + ms;
}
(async function main() {
try {
const name = await asyncP();
console.log(name);
} catch (error) {
console.log(error);
}
})();
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
//resolve(ms);
reject(new Error('reason');
}, ms);
});
}
async function asyncP() {
const ms = await p(1000); //error 발생
return 'Mark: ' + ms;
}
(async function main() {
try {
const name = await asyncP();
console.log(name);
} catch (error) {
console.log(error); //이쪽으로 넘어옴
} finally {
console.log('end');
})();
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
//resolve(ms);
reject(new Error('reason');
}, ms);
});
}
//Promise
p(1000)
.then(() => p(1000))
.then(() => p(1000))
.then(() => {
console.log('3000ms 후에 실행');
});
//async await 더 선호되는 방식
async function process() {
await p(1000);
await p(1000);
await p(1000);
console.log('3000 ms 후에 실행');
};
process();
function p(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
//resolve(ms);
reject(new Error('reason');
}, ms);
});
}
// Promise.all
(async function main() {
const results = await Promise.all([p(1000), p(2000), p(3000)]);
console.log(results); //[1000, 2000, 3000]
})();
// Promise.race
(async function main() {
const result = await Promise.race([p(1000), p(2000), p(3000)]);
console.log(result); //1000
})();