JavaScript 비동기(2) promise, async, await

신은수·2023년 5월 6일
0

VanillaJS

목록 보기
8/11

1. Promise

  • 프로미스: 콜백 함수의 단점을 보완하기 위해 나온 비동기 처리에 사용되는 객체

  • 생성자 함수를 호출하여 인스턴스화할 수 있음

  • 프로미스의 생성자 함수는 resolve와 reject함수를 인자로 전달받는 콜백함수(비동기 함수)를 인자로 전달받음.

  • 비동기 처리 성공하여 resolve 함수를 호출하면 성공 상태(fulfilled)의 프로미스 객체가 반환되고, reject 함수가 호출 된 경우 실패 상태(rejected)의 프로미스 객체가 반환됨.

  • resolve함수가 실행되면 then 메소드가 자동으로 실행됨
    reject함수가 실행되면 catch 메소드가 자동으로 실행됨

    const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(1);
      }, 1000);
    });
    
    myPromise.then(n => {
      console.log(n);
    });
  • 이전 글의 콜백지옥 예시를 프로미스를 사용하여 고쳐보자

    function randomTime() {
        return Math.floor(Math.random() * 10) * 1000;
     }
    
    function getChicken() {
      return new Promise((resolve,reject)=>{
         setTimeout(() => {
            console.log('동묘시장 -> chicken');
           	resolve(getEgg)
          }, randomTime());
      })
    }
    
    function getEgg() {
       return new Promise((resolve,reject)=>{
         setTimeout(() => {
            console.log('동묘시장 -> chicken -> egg');
            resolve(getMeal)
          }, randomTime());
      })
    }
    
    function getMeal() {
       return new Promise((resolve,reject)=>{
         setTimeout(() => {
             resolve('동묘시장 -> chicken -> egg -> fried egg');
          }, randomTime());
      })
    }
    
    
    getChicken()
      .then((data) => data())
      .then((data) => data())
      .then((data) => console.log(data));
    // then method의 체이닝을 통해 비동기적으로 처리되는 코드의 실행 순서를 정할 수 있다.

2. async, await

1) async, await이란?

  • async와 await는 가장 최근에 나온 비동기 처리 패턴으로, 기존의 콜백함수와 프로미스
    의 단점을 보완한 문법

2) Promise 예제를 통해 알아보는 Promise문법의 단점

  • Promise예제

    function longWork2() {
              return new Promise((resolve, reject) => {
                  setTimeout(() => {
                      console.log("b를 만들어내는 오래걸리는 작업을 한다");
    
                      resolve(2);
                  }, 2000);
              });
          }
    
    function longWork() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log("a를 만들어내는 오래걸리는 작업을 한다");
                resolve(1);
            }, 1000);
        });
    }
    
    let a, b;
    longWork()
        .then((res) => {
            a = res;
            return longWork2();
        })
        .then((res) => {
            b = res;
            console.log(a + b);
        });
  • 생각보다 then을 여러 개 체이닝한 예제를 만드는 것이 쉽지는 않은 것 같다. 지금의 코드에서는 then절이 두 개 뿐이지만 then절이 여러번 체이닝 되면 보기 힘든 코드가 될 것이다. 이러한 단점을 보완하기위해 async, await이 나오게 되었다.

3) async, await 쓰는 방법

  • 함수를 선언할 때 함수의 앞부분에 async 키워드를 붙인다.
    → 함수에서 async를 사용하면, 해당 함수는 결과값으로 Promise 를 반환하게 된다.

  • Promise 앞부분에 await 을 넣어 해당 프로미스가 끝날 때 까지 기다렸다가 다음 작업을 수행할 수 있게 한다, 그리고 프라미스 객체의 fulfilled 값을 반환

    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    async function process() {
      console.log('안녕하세요!');
      await sleep(1000); // 1초쉬고
      console.log('반갑습니다!');
    }
    
    process().then(() => {
      console.log('작업이 끝났어요!');
    });
    
    //안녕하세요, 1초쉬고, 반갑습니다, 작업이 끝났어요!
  • 위의 Promise예제를 async, await로 바꿔보기

    function longWork2() {
              return new Promise((resolve, reject) => {
                  setTimeout(() => {
                      console.log("b를 만들어내는 오래걸리는 작업을 한다");
    
                      resolve(2);
                  }, 2000);
              });
          }
    
    function longWork() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log("a를 만들어내는 오래걸리는 작업을 한다");
                resolve(1);
            }, 1000);
        });
    
    (async function(){
       let a = await longWork(); 
       let b = await longWork2();
       console.log(a + b);
    })();
    
profile
🙌꿈꾸는 프론트엔드 개발자 신은수입니당🙌

0개의 댓글