일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- version mismatch
- web
- javscript
- A-Frame
- CI/CD
- array
- bootstrap
- PDO
- JavaScript
- 상태관리
- npx
- VR
- aframe
- vue-template-compiler
- vue
- vuex
- Node
- promise
- JS
- package-lock.json
- vuetify
- EM6
- auth0
- WebXR
- PHP
- AR
- Three.js
- WebVR
- Component
- 3d
- Today
- Total
대가는 결과를 만든다
async & await을 정리해보자 (ECMA 2017) 본문
ES6(ECMA2015) Promise를 좀 더 편하게 사용하기 위한 것으로 ES8(ECMA 2017)에서 발표된 문법이다.
async await에 대해 정리해본다.
1. async는 function 앞에 위치 한다.
2. async를 function 앞에 붙이면 해당 함수는 항상 Promise륻 return한다.
(항상 resolved promise로 값을 감싸 반환되도록 한다.)
async function f() {
return 1;
}
f().then(alert); // 1
// 혹은 명시적으로 promise를 return (위와 동일)
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
3. await는 async함수 안에서만 동작한다.
4. await 키워드는 promise가 처리(settled)될 때까지 기다린다.
async function f() {
//1초 후 실행 완료되는 promise 함수
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000)
});
let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)
alert(result); // 1초 뒤 "완료!"를 출력. 위에서 기다리지 않았다면 아무것도 출력하지 않았을 것!
}
f();
=> 기다렸다가 프로미스가 처리되면 그 결과와 함께 실행이 재개된다. 프로미스가 처리되길 기다리는 동안 엔진이 다른 일을 할 수 있기 때문에, CPU 리소스 낭비되지 않는다.
5. await는 promise.then보다 가독성을 개선하고 쉽게 쓸 수 있도록 한 문법이다.
//기존 promise 이용 문법
function showAvatar(){
return 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(()=>{
//3초후 실행할 부분
img.remove();
resolve();
}, 3000);
});
}
//async & await 문법을 이용한 방법
async function showAvatar() {
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();
}
showAvatar();
6. promise chaning의 경우 더욱 체감할 수 있다.
//promise chaining
//json 파일 가져오기
function loadJson(url) {
return fetch(url)
.then(response => response.json());
}
//user 정보 가져오기
function loadGithubUser(name) {
return fetch(`https://api.github.com/users/${name}`)
.then(response => response.json());
}
//아바타 가져오기
function showAvatar(githubUser) {
return 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);
});
}
//json 파일 가져와서 url로 user정보를 가져온 후 avatar를 가져오는 함수 실행
loadJson('/article/promise-chaining/user.json')
.then(user => loadGithubUser(user.name))
.then(showAvatar)
.then(githubUser => alert(`Finished showing ${githubUser.name}`));
// ...
//await & async를 이용한 비동기 chaning 해결
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();
7. await는 'thenable 객체(then 메서드가 있는 호출 가능한 객체)'를 받을 수 있다.
: .then이 구현되어있으면서 프라미스가 아닌 객체를 받으면, 내장 함수 resolve와 reject를 인수로 제공하는 메서드인 .then을 호출한다.
//데모 thenable class 정의
class Thenable {
constructor(num) {
this.num = num;
}
//then 메서드
then(resolve, reject) {
alert(resolve);
// 1000밀리초 후에 이행됨(result는 this.num*2)
setTimeout(() => resolve(this.num * 2), 1000); // (*)
}
};
async function f() {
// 1초 후, 변수 result는 2가 됨
let result = await new Thenable(1); //then내부 resolve 혹은 reject가 호출되길 기다림
alert(result);
}
f();
8. await promise는 promise 객체 result를 return, reject된 경우 throw문 처럼 error를 던진다. 그리고 try..catch로 잡을 수 있다.
//아래 두 코드는 동일하다.
async function f() {
await Promise.reject(new Error("에러 발생!"));
}
async function f() {
throw new Error("에러 발생!");
}
async function f() {
//await promise에서 발생될 수 있는 error를 catch 하기 위함
try {
let response = await fetch('http://유효하지-않은-주소');
let user = await response.json();
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
9. promise.all도 await를 사용 가능 하다.
// 프라미스 처리 결과가 담긴 배열을 기다립니다.
let results = await Promise.all([
fetch(url1),
fetch(url2),
...
]);
참고
https://ko.javascript.info/async-await
'개발 > Javascript' 카테고리의 다른 글
iterator/iterable, generator에 대한 정리 (0) | 2020.03.24 |
---|---|
자주 햇갈리는 javascript ES, ECMA 표기법 정리 (0) | 2020.03.23 |
javascript "this"에 대하여 (0) | 2020.03.13 |
call, apply, bind에 대한 정리 (0) | 2020.03.13 |
promise sequence 처리 패턴 - 1 (0) | 2020.01.07 |