function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
resolveAfter2Seconds()
.then(
resolved => {
console.log(resolved);
return 'done';
}
);
async function asyncCall() {
console.log(await resolveAfter2Seconds(););
return 'done'
}
asyncCall();
// .then() 사용가능. async 함수의 반환값은 promise기 때문이다.
async 함수에는 await
가 포함될 수 있다. await는 async
함수 실행을 일시 중지한다. 그리고 전달된 Promise
의 resolve를 기다린다. 그리고 async
함수의 실행을 다시 시작한다.
asyncCall()에서 await resolveAfter2Seconds()
는 console.log의 호출이 resolveAfter2Seconds promise가 resolve될 때까지 기다린다. resolve 된 후에 그 값을 출력한다.
왜 async/await가 더 나을까?
// promise
const makeRequest = () =>
getJSON().then(data => {
console.log(data);
return "done";
});
makeRequest();
// async-await
const makeRequest = async () => {
console.log(await getJSON());
return "done";
};
makeRequest();
response를 해결하기 위한 비동기 함수 불필요
data란 이름의 변수를 선언 및 사용할 필요 없음
동기와 비동기 에러 모두 try.catch로 해결 가능.
promise는 동기, 비동기 에러를 커버하기 위해
promise 상에서 .catch를 사용해야하는 복잡함
promise
const makeReq = () => {
try {
getJSON()
.then(res => {
// JSON.parse가 에러를 일으키는 경우, catch문에서 잡지 못한다. promsie 안쪽에서 발생했기 때문이다.
// 얘를 잡기 위해 promise의 .catch 이용
const data = JSON.parse(res);
console.log(data);
})
// 비동기 error를 핸들링 하기 위한 catch문
.catch(err => {
console.log(err);
});
// then 내부(async error)의 에러를 캐치하지 못함.
} catch (err) {
console.log(err);
}
};
async-await는 1개의 catch문으로 모든 영역 커버
async-await
const makeReq = async () => {
try {
const res = await getJSON();
const data = JSON.parse(res);
console.log(data);
} catch (err) {
console.log(err);
}
};
const makeRequest = () => {
return getJSON().then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data).then(moreData => {
console.log(moreData);
return moreData;
});
} else {
console.log(data);
return data;
}
});
};
코드가 너무나 불편해보인다. async-await로 nesting을 줄여보자.
const makeReq = async () => {
const data = await getJSON();
if (data.needsAnotherReq) {
const moreData = await makeAnotherReq(data);
console.log(moreData);
return moreData;
} else {
console.log(data);
return data;
}
};
promise1 호출 후 여기서 return 값을 활용하여 promise2를 호출하고, promise3을 호출하기 위해 promise1과 promise2의 결과값을 사용한다. 그렇기 하기 위해 다음과 같은 코드를 작성한다.
const makeReq = () => {
return promise1().then(res1 => {
return promise2(res1).then(res2 => {
return promise3(res1, res2);
});
});
};
이걸 좀 줄이기 위해 promise.all을 사용해보자.
const makeReq = () => {
return promise1()
.then(res1 => {
return Promise.all([res1, promise2(res1)]);
})
.then(([res1, res2]) => {
return promise3(res1, res2);
});
};
promise nesting을 피하기 위해 res1과 res2가 배열로 묶은건데 코드 가독성을 떨어뜨린다. 걍 async-await를 쓰면 굉장히 단순해진다.
const makeReq = async () => {
const res1 = await promise1();
const res2 = await promise2(res1);
return promise3(res1, res2);
};
참고