-
오늘은 Promise에 이어서 aync & await에 대해 학습해보려고 한다.
Async Function
- async function 선언은 AsyncFunction 객체를 반환하는 하나의 비동기 함수를 정의
- 암시적으로 Promise를 사용하여 결과를 반환, 그러나 비동기 함수를 사용하는 코드의 구문, 구조는 표준 동기 함수와
많이 비슷함.
❓ AsyncFunction
- 자바스크립트에서 모든 비동기 함수는 사실상 AsyncFunction 객체이다.
- AsynFunction 생성자는 새로운 async function 객체를 만든다.
기본 문법
// * getRandomFriendName 함수는 promise // 선언문 async function getFriends () { const name1 = await getRandomFriendName(); const name2 = await getRandomFriendName(); const name3 = await getRandomFriendName(); const name4 = await getRandomFriendName(); return [name1, name2, name3, name4] } // 표현식 const helloWorld = async function () { // 상단과 동일함. } (async function() { // IIFE(즉시실행함수)로도 실행할 수 있음. })
- async 함수에는 await 식이 포함될 수 있으며, 이 식은 async 함수의 실행을 일시 중지하고 전달된 Promise의 해결을 기다린 다음 async 함수의 실행을 다시 시작하고 완료후 값을 반환.
- async 함수는 항상 promise를 리턴한다. 만약에 함수의 반환값이 명시적으로 promise가 아니라면 암묵적으로 promise로 감싸진다.
function getMyFriendName () { return '영희'; // 이 부분이 암묵적으로 return Promise.resolve('영희')로 변환됨 }
- async 함수의 본문은 0개 이상의 await문으로 분할됨.
- 첫번째 await문을 포함하는 최상위 코드는 동기적으로 실행되고, await문이 없는 async함수는 동기적으로 실행됨.
- 단, await문이 있다면 async함수는 항상 비동기적으로 완료됨.
MDN 예시 뜯어보기
// ⏹ Promise 함수 소개 // slowPromise() : 2초 후 실행 // fastPromise() : 1초후 실행 // 1️⃣ 잇달아 일어남 // 결과 값 : 2초 후 slowPromise → 1초 후 fastPromise var sequentialStart = async function () { console.log('==SEQUENTIAL START=='); const slow = await slowPromise(); const fast = await fastPromise(); } // 2️⃣ 동시에 일어남 // 결과 값 : 2초 후 slowPromise, 그 뒤에 이어서 fastPromise가 바로 리턴됨. var concurrentStart = async function () { console.log('==CONCURRENT START with await=='); const slow = slowPromise(); // 처음에 await을 안붙여주기 때문에 바로 시작됨. const fast = fastPromise(); console.log(await slow); console.log(await fast); // 먼저 결과 값을 받았지만, await문 때문에 기다린 후 slow가 반환되면 바로 리턴. } var stillConcurrent = function () { console.log('==CONCURRENT START with Promise.all=='); Promise.all([slowPromise(), fastPromise()]).then((messages) => { console.log(messages[0]); // slow console.log(messages[1]); // fast }); } // 3️⃣ 병렬적으로 진행됨. // 결과 값 : 1초 후 fast 리턴, 2초 후 slow 리턴 var parallel = function () { console.log('==PARALLEL with Promise.then=='); slowPromise().then((message) => console.log(message)); fastPromise().then((message) => console.log(message)); }
await
- Promise를 기다리기 위해 사용
- async function 내부에서만 사용
- 결론 : 그래서 await이 필요하다.
- await은 위 MDN 예시 뜯어보기를 보면 알겠지만 정말 다양한 방식으로 비동기 코드를 처리할 수 있고, then()으로 계속 체이닝을 하는 것이 아닌 마치 일반 함수를 호출하는 듯한 작성 방식으로 훨씬 가독성이 높아졌다.
function getRandomNumber(time) { return new Promise((resolve, reject) => { const randomNum = Math.floor(Math.random() * 100); setTimeout(function () { resolve(randomNum); }, time) }) } // Async function async function getRandNumsWithAsync() { const num1 = await getRandomNumber(100); const num2 = await getRandomNumber(200); const num3 = await getRandomNumber(300); const num4 = await getRandomNumber(400); const num5 = await getRandomNumber(500); return `${num1}/${num2}/${num3}/${num4}/${num5}` } // promise function getRandNumWithPromiseTwo() { return getRandomNumber(100).then(num1 => { return getRandomNumber(200).then(num2 => { return getRandomNumber(300).then(num3 => { return getRandomNumber(400).then(num4 => { return getRandomNumber(500).then(num5 => { return `${num1}/${num2}/${num3}/${num4}/${num5}` }) }) }) }) }) } // promise2 function getRandNumWithPromiseTwo() { return getRandomNumber(100).then(num1 => getRandomNumber(200).then(num2 => getRandomNumber(300).then(num3 => getRandomNumber(400).then(num4 => getRandomNumber(500).then(num5 => `${num1}/${num2}/${num3}/${num4}/${num5}`))))) }
- 또 다른 콜백 지옥을 만날 수 있음. 혹시 몰라서 return문을 빼볼까싶어서 탄생한게 promise2 ㅎㅎ...
- async는 진짜 함수에서 값을 받아온 다음에 그냥 쓰는 느낌이라 가독성이 확 높아졌다. 하지만 promise가 더 유용한 경우가 있다고 하는데 이에 대해서는 한번 검색이 필요할거 같다
😂 예-스 드디어 비동기 프로그래밍 기초에 대해서 공부하게 되었다.
해당 개념이 어려울거 같다고 항상 미뤘는데 리덕스 thunk 공부하면서 공부를 안할 수가 없었던 부분 !
생각보다 개념이 난해하지는 않았던거 같다. 다만 어떻게 써야 더 효율적인지 그런 실무적인 부분은 다른 사람의 코드를 좀 봐봐야할듯?
아마 각각의 데이터의 관계에 따라 어떤게 더 효율적인지 확인 후 사용하는 거 같다, 왜냐면 Promise에도 다양한 메서드 (all, race, any 등)이 있기 때문에 경우에 따라서는 이게 더 유용할 거 같기 때문이다.
참고자료
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
댓글