Js- async, await
in Javascript
참고
[1] https://ko.javascript.info/async-await
async 함수
- function 앞에 async를 붙이면 해당 함수는 항상 Promise 객체를 반환한다.
- Promise가 아닌 값(value)를 반환하더라도 이행된(resolved) Promise 객체가 반환되도록 한다.
- Promise가 resolved 되었다는 것은 excutor 함수가 실행되었다는 소리이다. resolved(value)
async function f() { return 1; // return new Promise(() => resolve(1)); } f().then(alert); // 1
await
- Promise 객체의 excutor 함수의 결과물은 then, catch, finally 메소드로만 받을 수 있었다. 하지만 이 메소드들은 background에서 비동기적으로 실행된다.
- await는 excutor 함수의 결과물을 다루는 방법 중 하나로 then 메소드와는 다르게 동기적(결과가 처리될 때까지 기다림)으로 처리한다.
- await는 async 함수 블록 안에서만 동작한다… 왜 이렇게 만든지는 모르겟지만…
// then 메소드 이용 // 1, 3, 2 출력 async function f(){ promise = new Promise(resolve => resolve(2)); console.log(1); promise.then(result => console.log(result)); console.log(3); } f(); // await 메소드 이용 // 1, 2, 3 출력 async function g(){ promise = new Promise(resolve => resolve(2)); console.log(1); prac_await = await promise; console.log(prac_await); console.log(3); } g();await의 thenable 객체 받기
- then 메소드에서 thenable(then메소드가 있는 Promise가 아닌 객체) 객체를 받을 수 있었던 것 처럼, await에도 thenable 객체를 받을 수 있다.
- await는 thenable 객체를 만나면 then 메소드를 실행하고 resolve, reject 함수가 call될 때까지 기다린 후(동기), 그 결과값(result or error)을 받는다.
function Thenable(num) { this.num = num; this.then = function(resolve, reject) { setTimeout(() => resolve(this.num * 2), 1000); }; } async function f() { let result = await new Thenable(1); console.log(result); } f();Promise.all
- await 구문 또한 Promise.all 메소드를 사용할 수 있다.
- 결과물을 배열로 받는다.
let results = await Promise.all([ fetch(url1), fetch(url2), ... ]);
에러 핸들링
- await는 기존의 then, catch 에러 핸들링과 다르게 함수 블럭 안에 try…catch 구문을 사용할 수 있다. 비동기는 try…catch 구문을 사용할 수 없다.
async function practice() { try{ let response = await fetch('http://유효하지-않은-주소'); let user = await response.json(); } catch(err) { alert(err); } }- try…catch 구문이 아닌 catch 메소드를 사용해서 에러 핸들링을 할 수도 있다.
async function f() { let response = await fetch('http://유효하지-않은-url'); } f().catch(alert);
then 메소드 ==> async, await 코드 예시
// then 메소드 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); }); } // async, await 메소드 async function showAvatar(githubUser){ let img = document.createElement('img'); img.src = githubUser.avatar_url; img.className = "promise-avatar-example"; document.body.append(img); await new Promise((resolve, reject) => setTimeout(resolve, 3000)); // 단순히 3초 기다림. img.remove(); return githubUser; }