본문 바로가기

프로그래밍/웹

자바스크립트 async / await

반응형

 

 

async & await

  • 콜백 지옥처럼, 프로미스 체이닝도 반복되면 코드 가독성 저하
  • 비동기 처리를 위한 async/await은 Promise를 간편하게 동기적으로 실행하는 것처럼 보이게 만드는 API
  • 새로 추가된 문법이 아닌 기존에 존재하는 Promise를 간단 조작하기 위한 syntax sugar
  • async 키워드가 붙은 함수는 항상 Promise를 반환


async
기존 방식(Promise)
 // 프로미스 사용 시 반드시 resolve와 reject를 호출해야 함
 function fetchUser() {
   return new Promise((resolve, reject) => {
     // return `ellie`; // 프로미스 pending 상태
 		resolve(`ellie`); // 프로미스 fulfilled 상태
 		// reject(new Error(`error`)); // 프로미스 rejected 상태
   });
 }
 
 const user = fetchUser();
 // console.log(user);
 user.then(user => console.log(user));


async 사용
  • async 함수 사용 시 함수 코드 블록이 자동으로 Promise로 변환됨
 // 1. 함수 선언식
 async function fetchUser() {
   return `ellie`;
 }
 
 // 2. 함수 표현식
 const fetchUser = async function() {
   return `ellie`;
 };
 
 // 3. 화살표 함수
 const fetchUser = async () => {
   return `ellie`;
 };
 
 // fetchUser().then(data => console.log(data)); // 함수로 바로 호출
 const user = fetchUser(); // 변수에 할당해서 호출
 user.then(data => console.log(data));
 console.log(user);



await
기존 방식(Promise)
 function delay(ms) {
   return new Promise (resolve => setTimeout(resolve, ms));
 }
 
 function getApple() {
   return delay(1000)
   .then(() => `🍎`);
 }
 function getBanana() {
   return delay(1000)
   .then(() => `🍌`);
 }
 
 function pickFruits() {
   return getApple()
   .then(apple => {
     return getBanana().then(banana => `${apple} + ${banana}`);
   });
 }
 pickFruits().then(result => console.log(result));


await 사용
  • Promise가 처리될 때까지 함수 실행을 보류
  • Promise의 .then 메소드를 await으로 변경
  • await 키워드는 async 함수 내부에서만 사용 가능
 function delay(ms) {
   return new Promise (resolve => setTimeout(resolve, ms));
 }
 
 async function getApple() {
   await delay(1000);
   // throw new Error(`error: apple`); // error 발생
   return `🍎`;
 }
 async function getBanana() {
   await delay(1000);
   // throw new Error(`error: banana`);
   return `🍌`;
 }
 
 async function pickFruits() {
   let apple = null;
   try {
     apple = await getApple();
   } catch(error) {
     console.log(error);
   }
   let banana = null;
   try {
     banana = await getBanana();
   } catch(error) {
     console.log(error);
   }
   return `${apple} + ${banana}`;
 }
 pickFruits().then(result => console.log(result));

 

await 병렬 처리
  • 위 예제 코드에서 getApple과 getBanana는 서로 독립적인 코드인데 순차적으로 실행됨 → 비효율적
 function delay(ms) {
   return new Promise (resolve => setTimeout(resolve, ms));
 }
 
 async function getApple() {
   await delay(1000);
   return `🍎`;
 }
 async function getBanana() {
   await delay(1000);
   return `🍌`;
 }
 
 // async/await 병렬 처리
 async function pickFruits() {
   // 프로미스 객체는 선언 즉시 바로 실행됨
   // getApple과 getBanana는 병렬(독립적)로 실행됨
   const applePromise = getApple();
   const bananaPromise = getBanana();
   // 동기화
   const apple = await applePromise; 
   const banana = await bananaPromise;
   return `${apple} + ${banana}`;
 }
 pickFruits().then(result => console.log(result));
 
 // Promise 사용 - 모든 Promise가 수신될 때까지 대기
 function pickAllFruits() {
   return Promise.all([getApple(), getBanana()]).then(fruits => {
     return fruits.join(` + `);
   });
 	// return Promise.all([getApple(), getBanana()]);
 }
 pickAllFruits().then(console.log);
 
 // 비동기 처리중 먼저 리턴되는 함수 출력
 function pickOnlyOne() {
   return Promise.race([getApple(), getBanana()]);
 }
 pickOnlyOne().then(console.log);

참고 : https://www.youtube.com/watch?v=tJieVCgGzhs&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=2








반응형