스터디
[JavaScript] async/await 본문
< async와 await >
async와 await라는 특별한 문법을 사용하면 Promise를 좀 더 편하게 사용할 수 있다.
> async
async는 function 앞에 위치한다.
async function func() {
return 1;
}
function 앞에 async를 붙이면 해당 함수는 항상 Promise를 반환한다.
Promise가 아닌 값을 반환하더라도 이행 상태의 Promise(resolved promise)로 값을 감싸 이행된 Promise가 반환되도록 한다.
아래 예시의 함수를 호출하면 result가 1인 이행 Promise가 반환된다.
async function func() {
return 1;
}
func.then(alert); // 1
명시적으로 Promise를 반환하는 것도 가능한데 결과는 동일하다.
async function func() {
return Promise.resolve(1);
}
func.then(alert); // 1
async가 붙은 함수는 반드시 Promise를 반환하고, Promise가 아닌 것은 Promise로 감싸 반환한다.
또 다른 await는 async 함수 안에서만 동작한다.
> await
await 문법은 다음과 같다.
// await는 async 함수 안에서만 동작한다.
let value = await promise;
자바스크립트는 await 키워드를 만나면 Promise가 처리될 때까지 기다린다. 결과는 그 이후에 반환된다.
async function func() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('완료'), 1000);
});
let result = await promise; // Promise가 이행될 때까지 기다림
alert(result); // 완료
}
func();
함수를 호출하고 함수 본문이 실행되는 도중에 await가 있는 부분에서 실행이 잠시 중단되었다가 Promise가 처리되면 실행이 재개된다.
이때 Promise 객체의 result 값이 변수 result에 할당된다.
따라서 위 예시를 실행하면 1초 뒤에 '완료'가 출력된다.
await는 말 그대로 Promise가 처리될 때까지 함수 실행을 기다리게 만든다.
Promise가 처리되면 그 결과와 함께 실행이 재개된다.
Promise가 처리되길 기다리는 동안에는 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에 CPU 리소스가 낭비되지 않는다.
await는 promise.then보다 가독성이 좋고 쓰기도 쉽다.
주의해야 할 점은 async가 아닌 일반 함수에 await을 사용하면 문법 에러가 발생한다.
function func() {
let promise = Promise.resolve(1);
let result = await promise; // SyntaxError: await is only valid in async functions and the top level bodies of modules
}
> 에러 핸들링
Promise가 정상적으로 이행되면 await promise는 Promise 객체의 result에 저장된 값을 반환한다.
반면 Promise가 거부되면 마치 throw문을 작성한 것처럼 에러가 던져진다.
async function func() {
await Promise.reject(new Error('에러 발생'));
}
async function func() {
throw new Error('에러 발생');
}
실제 상황에서는 Promise가 거부되기 전에 약간의 시간이 지체되는 경우가 있다.
이런 경우에는 await가 에러를 던지기 전에 지연이 발생한다.
await가 던진 에러는 throw가 던진 에러를 잡을 때처럼 try/catch를 사용해 잡을 수 있다.
async function func() {
try {
let response = await fetch('http://유효하지-않은-주소');
} catch (err) {
alert(err); // TypeError: failed to fetch
}
}
func();
에러가 발생하면 제어 흐름이 catch 블록으로 넘어간다.
여러 줄의 코드를 try로 감싸는 것도 가능하다.
async function func() {
try {
let response = await fetch('http://유효하지-않은-주소');
let user = await response.json();
} catch (err) {
// fetch와 response.json에서 발생한 에러 모두 여기서 잡는다.
alert(err);
}
}
func();
https://ko.javascript.info/async-await
async와 await
ko.javascript.info
'백엔드' 카테고리의 다른 글
MVC 패턴 (2) | 2023.04.07 |
---|---|
[JavaScript] 동기? 비동기? (0) | 2023.04.06 |
JavaScript promise (1) | 2023.04.06 |
HTTP 상태 코드 (0) | 2023.04.06 |
HTTP Method (0) | 2023.04.06 |