콜백 지옥에서 벗어나기 위해 프로미스 패턴을 사용하는 것처럼, 프로미스 패턴의 단점을 극복하기 위해 async/await를 사용한다. - ES2017(ES8)
Promise 문법
function p() {
return new Promise((resolve, reject) => {
resolve('hello');
// or reject(new Error('error');
});
}
p().then((n) => console.log(n));
async 문법
async function p2(){ // async을 지정해주면 Promise를 리턴하는 함수로 만들어준다.
return 'hello2'; // 리턴값은 Promise{<resolved>: "hello2"} 자동 resolve해준다는걸 알 수 있다.
// reject는 throw 에러를 날리면 된다.
}
p2().then((n) => console.log(n));
한눈에 봐도 매우 직관적인 코드로 변했다고 느낄 수 있다.
함수에 async만 붙이면 자동 Promise객체로 인식되고 return값은 resolve()값과 똑같다.
return을 문자열로 했다고 해서 일반 함수처럼 정말 문자열이 리턴되는 것은 아니다.
앞서 Promise를 리턴하게 해주는 지정자가 async라고 했다.
그래서 리턴값은 Promise{<resolved>: "hello2"}
- async가 붙은 함수는 프라미스를 반환하고, 프라미스가 아닌 것은 프라미스로 감싸 반환한다.
- await 키워드를 만나면 프라미스가 처리(settled)될 때까지 기다린다.
그리고 프라미스가 처리가 완료되어 resolve(값) 되면 값만 따로 추출해서 리턴한다.
await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법이다. promise.then보다 가독성 좋고 쓰기도 쉽다.
async/await가 Promise를 완벽히 대체하는 것이 아니다.
비동기는 Promise객체로 처리하고
async/await는 비동기를 동기식으로 처리하는 기법이다.
기존에는 Promise에 직접 .then()을 통해 동기 처리를 했지만,
await를 사용하면 바로 동기 처리가 되기 때문이다.
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function helloAsync() {
return delay(3000).then(() => {
return 'hello Async';
});
}
helloAsync().then((res) => {
console.log(res); // 3초 뒤 'hello Async'
});
원하는 동작은 3초 기다렸다가 hello Async반환하는 것인데 너무 거창하다. await을 사용하여 간소화해줄 수 있다.
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function helloAsync() {
await delay(3000);
return 'hello async';
}
helloAsync().then((res) => {
console.log(res); // 3초 뒤 'hello Async'
});
await 키워드를 비동기 함수의 호출 앞에 붙이게 되면 비동기 함수가 동기적으로 작동하게 된다.
await 키워드가 붙은 함수의 호출은 함수 호출이 끝나기 전까지 그 뒤의 코드를 실행하지 않는다.
delay가 호출되면서 3초간 delay 하는 것이 끝날 때까지 return 'hello async'는 기다리고 있는다.
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function helloAsync() {
await delay(3000);
return 'hello async';
}
async function main() {
const res = await helloAsync();
console.log(res);
}
main();
main함수에서 helloAsync의 결과 값을 await을 사용하여 호출해보았다.
참고 자료:
'개발자의 공부 > JS' 카테고리의 다른 글
[JS]데이터 불변성(Immutability) (1) | 2022.09.29 |
---|---|
[JS]스코프(Scope) (2) | 2022.09.26 |
[JS]재귀 함수, 중첩 함수, 순수&비순수 함수 (0) | 2022.09.21 |
[JS문법]객체(Object)란? (0) | 2022.09.13 |
JS 코드 개선+Optional chaining+null 병합 연산자 (1) | 2022.09.10 |