비동기 프로그래밍에 대해 학습하던 중 Callback, Promise, Async&await, Ajax, XMLHttpRequest, fetch API에 대한 개념을 보다 명확하게 정리하고자 작성하는 글입니다.
2편에서는 Promise에 대해서 알아봤습니다. 이번 편은 Async&await에 대해서 알아보겠습니다.
Async&await
Async&await는 Promise와 마찬가지로 비동기를 위해 사용되는 함수이고 내부적으로 Promise 객체를 사용하여 결과를 반환합니다. Promise를 좀 더 간편하게 사용할 수 있다는 것을 의미합니다.
async는 비동기 함수임을 명시하는 키워드이며 보통 async function() {} 와 같이 작성합니다.
async 키워드를 붙이면 해당 코드 블럭이 Promise로 바뀌게 됩니다.
await는 Promiose를 기다리기 위해서 사용되고 async function 내부에서만 사용이 가능합니다.
기존 방식에서 작업하는데에 1초가 소요되는 아래와 같은 코드가 있다고 해보겠습니다.
timer(1000, function(){
console.log('작업');
timer(1000, function() {
console.log('작업');
timer(1000, function() {
console.log('작업');
});
});
});
Promise를 이용하여 아래와 같이 변경이 가능합니다.
timer(1000)
.then(function() {
console.log('작업');
return timer(1000);
})
.then(function() {
console.log('작업');
return timer(1000);
})
.then(function() {
console.log('작업');
return timer(1000);
})
이처럼 Callback 함수를 인자로 직접 넘기는 방식보다 Promise를 이용하여 가독성 좋게 바뀌었습니다.
하지만 Async&await를 이용하면 더욱 더 가독성 좋게 바꿀 수 있습니다.
async function run() {
await timer(1000)
console.log('작업');
await timer(1000)
console.log('작업');
await timer(1000)
console.log('작업');
}
run();
좀 더 실전적인 예제를 보겠습니다.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000);
return '사과';
}
async function getBanana() {
await delay(1000);
return '바나나';
}
function pickFruits() {
return getApple().then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`);
});
}
pickFruits().then(console.log);
사과와 바나나를 가져오는 메서드에 async 키워드를 붙이고 delay 메서드를 호출하는데 await 키워드를 붙였다고 생각해보겠습니다.
이렇게되면 1초가 지난 뒤 사과를 받아오고 다시 1초가 지난 뒤 바나나를 받아와 '사과 + 바나나' 가 출력되게 됩니다.
하지만 pickFruits 메서드를 보면 Callback 지옥과 비슷한 구조로 진행되어지고 있는 것을 볼 수 있습니다.
Promise도 중첩적으로 chaining을 하게 되면 Callback 지옥과 비슷한 문제점이 발생할 것 처럼 보입니다.
이러한 문제도 async 키워드를 통해서 해결 할 수 있습니다.
async function pickFruits() {
const apple = await getApple(); // 1초 소요
const banana = await getBanana(); // 1초 소요
return `${apple} + ${banana}`;
}
과일을 가져오는 메서드에 async 키워드를 붙이고 과일을 가져오는 각각의 메서드의 리턴값에도 await를 붙이면 보다 훨씬 편하게 사용할 수 있습니다.
여기서 비효율적인 한가지 문제점이 있습니다.
각각의 과일들을 가져오는데에 1초 씩(총 2초)가 소요됩니다. 사과와 바나나를 가져오는데는 연관되어 있지 않기 때문에 사과를 받아오고나서 바나나를 가져올 필요가 없습니다.
따라서 각각의 Promise를 미리 만들고 해당 프로미스에 대해 await 키워드를 붙여주면 각각의 과일 가져오는데에 총 1초가 소요됩니다. 병렬적으로 사과와 바나나를 가져오게 됩니다.
async function pickFruits() {
const applePromise = getApple();
const bananaPromise = getBanana();
const apple = await applePromise;
const banana = await bananaPromise;
return `${apple} + ${banana}`;
}
위의 코드 보다 개선된 각각의 작업을 병렬적으로 실행시키는 유용한 Promise의 기능이 있습니다.
바로 Promise.all() 을 사용하는 것입니다.
병렬적으로 실행시키는 Promise를 인자로 넣어서 출력할 수 있습니다.
function pickFruits() {
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join(' + '));
}
다음글
비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 4
참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/await
https://www.youtube.com/watch?v=aoQSOZfz3vQ
https://www.youtube.com/watch?v=1z5bU-CTVsQ&index=3
https://www.youtube.com/watch?v=a5AzftkvW9U&index=5
'JavaScript' 카테고리의 다른 글
비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 4 (0) | 2022.03.20 |
---|---|
비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 2 (0) | 2022.03.18 |
비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 1 (1) | 2022.03.17 |
Webpack이란? (0) | 2021.09.14 |