async 함수
async는 function 앞에 위치합니다.
function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환합니다.
async function f(){
return 1;
}
// 위와 같은 함수
async function f() {
return Promise.resolve(1);
}
await 함수
await는 async 함수 안에서만 동작합니다. await는 말 그대로 프라미스가 처리될 때까지 함수 실행을 기다리게 만듭니다. 처리되면 그 결과와 함께 실행이 재개됩니다.
프라미스가 처리되길 기다리는 동안엔 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않습니다.
예시
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)
alert(result); // "완료!"
}
f();
await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법입니다.
promise .then 을 async/await 로 변환 예시
promise chaning 에서의 예시
fetch('/article/promise-chaining/user.json')
.then(response => response.json()) // json 읽기
.then(user => fetch(`https://api.github.com/users/${user.name}`)) // 사용자 정보 읽기
.then(response => response.json())
.then(githubUser => new Promise(function(resolve, reject) { // 아바타 보여주기
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
setTimeout(() => {
img.remove();
resolve(githubUser); //
}, 3000);
}))
// 3초 후 동작함
.then(githubUser => alert(`${githubUser.name}의 이미지를 성공적으로 출력하였습니다.`));
async / await 로 변환
async function showAvatar() {
// JSON 읽기
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();
// github 사용자 정보 읽기
let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
let githubUser = await githubResponse.json();
// 아바타 보여주기
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
// 3초 대기
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();
return githubUser;
}
showAvatar();
다른 사용예시들
(async () => {
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();
...
})();
에러 핸들링
try{ ... } catch { ... } 를 이용
async function f() {
try {
let response = await fetch('http://유효하지-않은-주소');
let user = await response.json();
} catch(err) {
// fetch와 response.json에서 발행한 에러 모두를 여기서 잡습니다.
alert(err);
}
}
다시던지기를 이용한 코드 예시
.then 이용
class HttpError extends Error {
constructor(response) {
super(`${response.status} for ${response.url}`);
this.name = 'HttpError';
this.response = response;
}
}
function loadJson(url) {
return fetch(url)
.then(response => {
if (response.status == 200) {
return response.json();
} else {
throw new HttpError(response);
}
})
}
// 유효한 사용자를 찾을 때까지 반복해서 username을 물어봄
function demoGithubUser() {
let name = prompt("GitHub username을 입력하세요.", "iliakan");
return loadJson(`https://api.github.com/users/${name}`)
.then(user => {
alert(`이름: ${user.name}.`);
return user;
})
.catch(err => {
if (err instanceof HttpError && err.response.status == 404) {
alert("일치하는 사용자가 없습니다. 다시 입력해 주세요.");
return demoGithubUser();
} else {
throw err;
}
});
}
demoGithubUser();
async/ awiat 이용
class HttpError extends Error {
constructor(response) {
super(`${response.status} for ${response.url}`);
this.name = 'HttpError';
this.response = response;
}
}
async function loadJson(url) {
let response = await fetch(url);
if (response.status == 200) {
return response.json();
} else {
throw new HttpError(response);
}
}
// 유효한 사용자를 찾을 때까지 반복해서 username을 물어봄
async function demoGithubUser() {
let user;
while(true) {
let name = prompt("GitHub username을 입력하세요.", "iliakan");
try {
user = await loadJson(`https://api.github.com/users/${name}`);
break; // 에러가 없으므로 반복문을 빠져나옵니다.
} catch(err) {
if (err instanceof HttpError && err.response.status == 404) {
// 얼럿 창이 뜬 이후에 반복문은 계속 돕니다.
alert("일치하는 사용자가 없습니다. 다시 입력해 주세요.");
} else {
// 알 수 없는 에러는 다시 던져집니다.
throw err;
}
}
}
alert(`이름: ${user.name}.`);
return user;
}
demoGithubUser();
예제
aysnc / await 이용하여 코드변경
function loadJson(url) {
return fetch(url)
.then(response => {
if (response.status == 200) {
return response.json();
} else {
throw new Error(response.status);
}
})
}
loadJson('no-such-user.json')
.catch(alert); // Error: 404
변경
async function loadJson(url) { // (1)
let response = await fetch(url); // (2)
if (response.status == 200) {
let json = await response.json(); // (3)
return json;
}
throw new Error(response.status);
}
loadJson('no-such-user.json')
.catch(alert); // Error: 404 (4)
참고자료
'프로그래밍 > JavaScript' 카테고리의 다른 글
[ JS ] 프라미스와 async / await : 프라미스화 (0) | 2024.06.05 |
---|---|
[ JS ] 프라미스와 async / await : 프라미스 API (0) | 2024.06.05 |
[ JS ] 프라미스와 async / await : 프라미스와 에러 핸들링 (0) | 2024.06.05 |
[ JS ] 프라미스와 async / await : 프라미스 체이닝 (0) | 2024.06.04 |
[ JS ] 프라미스와 async / await : promise (0) | 2024.06.04 |