await/async
는 .then
보다 더 가독성도 좋고 쓰기도 쉽게 promise
의 result
값을 얻을 수 있도록 해주는 문법이다.
async
는 function
앞에 위치한다.
function
앞에 async
를 붙이면 그 function
은 항상 promise
를 반환한다.
다음 두 코드의 결과는 동일하다.
async function f() {
return 1;
}
f().then(alert); // 1
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
await
는 async
함수 안에서만 동작한다.
자바스크립트는 await
를 만나면 promise
가 처리될 때까지 기다리고, 처리되면 결과를 반환된다.
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
let result = await promise; // 프라미스가 이행될 때까지 기다린다.
alert(result);
}
f(); // 함수 호출
위 코드에서
await
를 쓰지 않았을 경우,
promise
의setTimeout
1초를 기다리지 않고result
에 담아alert
를 실행하기 때문에alert
창에는 "완료!"가 뜨지 않게된다.
await
는 promise
가 처리될 때까지 async
함수를 기다리게 한다.
promise
가 처리가 완료되면 그 결과와 함께 함수 실행이 재개된다.
promise
가 처리되길 기다리는 동안에 엔진이 다른 일을 할 수 있어 CPU 리소스가 낭비되지 않는다.
https://velog.io/@esc/promise-chaining 의 .then
대신 await/async
사용해보기
.then
let promise = fetch('https://jsonplaceholder.typicode.com/users/5')
.then(response => response.json())
.then(user => fetch(`https://api.github.com/users/${user.username}`))
.then(response => response.json())
.then(githubUser => new Promise(function(resolve, reject) {
let img = document.createElement('img');
img.src = githubUser.avatar_url;
document.body.append(img);
setTimeout(() => {
img.remove();
resolve(githubUser);
}, 3000);
}))
.then(githubUser => console.log(`username: ${githubUser.login}`));
.then
을await
로 바꾼다.await
를async
함수로 감싼다.
await/async
async function showAvatar() {
let response = await fetch('https://jsonplaceholder.typicode.com/users/5');
let user = await response.json();
let githubResponse = await fetch(`https://api.github.com/users/${user.username}`);
let githubUser = await githubResponse.json();
let img = document.createElement('img');
img.src = githubUser.avatar_url;
document.body.append(img);
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();
return console.log(`username: ${githubUser.login}`);
}
showAvatar();
try..catch
await
가 던진 에러는 throw
가 던진 에러를 잡을 때처럼 try..catch
를 사용해 잡을 수 있다.async function f() {
try {
let response = await fetch('http://유효하지-않은-주소');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
await
catch
블록으로 넘어간다. 여러 줄의 코드를 try
로 감싸는 것도 가능하다.async function f() {
try {
let response = await fetch('http://유효하지-않은-주소');
let user = await response.json();
} catch(err) {
// fetch와 response.json에서 발행한 에러 모두를 여기서 잡는다.
alert(err);
}
}
f();
.catch
try..catch
가 없으면 f()
에 .catch
를 추가하면 거부된 promise
를 처리할 수 있다.async function f() {
let response = await fetch('http://유효하지-않은-url');
}
// f()는 거부 상태의 프라미스가 된다.
f().catch(alert); // TypeError: failed to fetch