fetchSomething 함수는 프로미스를 반환한다. 그리고 JSON 오브젝트를 리졸브한다.
varfetchSomethingAPI=newPromise(resolve=>{setTimeout(()=>{ // JSON 객체라고 생각하자.resolve({ok:true,});},1500);});// promise versionvarfetchSomething=()=>{fetchSomethingAPI().then(result=>{constparsed=JSON.parse(result);console.log('result: ',parsed);returnparsed;}).catch(e=>console.error(e));};// async-await verisonvarfetchSomething2=async()=>{try{varresult=awaitfetchSomethingAPI();constparsed=JSON.parse(result);console.log(parsed);returnparsed;}catch (e) {console.error(e);}};fetchSomething();fetchSomething2();// workfetchSomething.then(result=>console.log(result));// top level is not async fn..// var result = await fetchSomething;
위와 같이 보통 작성한다. 차이점은
함수를 async로 정의한다.
await는 async 함수 내부에서만 사용 가능하다.
async 함수는 암묵적으로 promise를 반환한다.
그래서 뭐가 더 좋은건데?
문법 차이를 알아봤다.
간결함.
.then, .catch 체이닝 없이 try-catch와 await 문으로 동기 문법처럼 깔끔하게 사용 가능하다.
에러 핸들링
async-await 는 동기와 비동기 에러 모두를 try/catch로 처리할 수 있다. promise는 try/catch로 promise 내부에서 발생한 에러(즉, 비동기 코드 내에서)는 잡아내지 못한다. .catch 체이닝을 호출하여 제어해야한다. (당연하지만 catch는 promise 외부에서 발생한 에러 잡아내지 못한다.)
이렇게 되면 promise는 try/catch와 .catch 두 곳에서 에러 핸들링을 해야한다.
중간값
promise1 -> promise1값으로 primise2 -> promise1과 promise2로 promise3 이와 같이 호출해야 한다면 then 체이닝의 depth가 깊어진다.
promise.all을 통해 nesting을 피할 수 있지만 then 체이닝은 그대로다.
async/await를 이용한다면 가독성이 높아진다.
디버깅
then에서 return 되는 arrow fn에 breakpoint 잡아내지 못한다. then으로 step-over 사용 불가. step-over는 동기 코드만 따라간다.
await는 breakpoint 걸 수 있고 step-over로 await문엥서 멈출 수 있다.
Summary
누가 async await보다 promise를 선호하는 이유를 다시 물어본다면..
가독성, 동기식으로 표현가능하고 then chaining을 보지 않아도 된다.
에러 핸들링
try catch문으로 둘 다 감쌌을 때 promise문의 비동기 에러는 try catch가 잡아내지 못한다. .catch()를 통해 에러 핸들링 해야한다. 즉, try-catch 와 catch문을 통해 두 번 에러 핸들링 해야한다.
async await의 try catch는 try 내부의 promise든 아니든 모두 에러 핸들링 가능하다.
breakpoint
then은 step over 불가, then에서 리턴하는 함수에 breakpoint 설정 불가. await문은 전부 가능.