async-await

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

resolveAfter2Seconds()
.then(
    resolved => {
        console.log(resolved);
        return 'done';
    }
);

async function asyncCall() {
  console.log(await resolveAfter2Seconds(););
  return 'done'
}

asyncCall();
// .then() 사용가능. async 함수의 반환값은 promise기 때문이다.

async 함수에는 await가 포함될 수 있다. await는 async 함수 실행을 일시 중지한다. 그리고 전달된 Promise의 resolve를 기다린다. 그리고 async 함수의 실행을 다시 시작한다.

asyncCall()에서 await resolveAfter2Seconds()는 console.log의 호출이 resolveAfter2Seconds promise가 resolve될 때까지 기다린다. resolve 된 후에 그 값을 출력한다.

왜 async/await가 더 나을까?

// promise
const makeRequest = () =>
  getJSON().then(data => {
    console.log(data);
    return "done";
  });

makeRequest();

// async-await
const makeRequest = async () => {
  console.log(await getJSON());
  return "done";
};

makeRequest();
  1. 간결함

  2. .then 코드 불필요

  3. response를 해결하기 위한 비동기 함수 불필요

  4. data란 이름의 변수를 선언 및 사용할 필요 없음

  5. 코드 nesting 줄어든다.

  6. 에러 핸들링

  7. 동기와 비동기 에러 모두 try.catch로 해결 가능.

  8. promise는 동기, 비동기 에러를 커버하기 위해

    • try/catch,

    • promise 상에서 .catch를 사용해야하는 복잡함

    • 이로인해 에러 처리 코드 중복된다.

promise

const makeReq = () => {
  try {
    getJSON()
      .then(res => {
        // JSON.parse가 에러를 일으키는 경우, catch문에서 잡지 못한다. promsie 안쪽에서 발생했기 때문이다.
        // 얘를 잡기 위해 promise의 .catch 이용
        const data = JSON.parse(res);
        console.log(data);
      })
      // 비동기 error를 핸들링 하기 위한 catch문
      .catch(err => {
        console.log(err);
      });
    // then 내부(async error)의 에러를 캐치하지 못함.
  } catch (err) {
    console.log(err);
  }
};

async-await는 1개의 catch문으로 모든 영역 커버

async-await

const makeReq = async () => {
  try {
    const res = await getJSON();
    const data = JSON.parse(res);
    console.log(data);
  } catch (err) {
    console.log(err);
  }
};
  1. 분기

const makeRequest = () => {
  return getJSON().then(data => {
    if (data.needsAnotherRequest) {
      return makeAnotherRequest(data).then(moreData => {
        console.log(moreData);
        return moreData;
      });
    } else {
      console.log(data);
      return data;
    }
  });
};

코드가 너무나 불편해보인다. async-await로 nesting을 줄여보자.

const makeReq = async () => {
  const data = await getJSON();
  if (data.needsAnotherReq) {
    const moreData = await makeAnotherReq(data);
    console.log(moreData);
    return moreData;
  } else {
    console.log(data);
    return data;
  }
};
  1. 중간값

promise1 호출 후 여기서 return 값을 활용하여 promise2를 호출하고, promise3을 호출하기 위해 promise1과 promise2의 결과값을 사용한다. 그렇기 하기 위해 다음과 같은 코드를 작성한다.

const makeReq = () => {
  return promise1().then(res1 => {
    return promise2(res1).then(res2 => {
      return promise3(res1, res2);
    });
  });
};

이걸 좀 줄이기 위해 promise.all을 사용해보자.

const makeReq = () => {
  return promise1()
    .then(res1 => {
      return Promise.all([res1, promise2(res1)]);
    })
    .then(([res1, res2]) => {
      return promise3(res1, res2);
    });
};

promise nesting을 피하기 위해 res1과 res2가 배열로 묶은건데 코드 가독성을 떨어뜨린다. 걍 async-await를 쓰면 굉장히 단순해진다.

const makeReq = async () => {
  const res1 = await promise1();
  const res2 = await promise2(res1);
  return promise3(res1, res2);
};

참고

async-await가 promise를 사라지게할 수 있는 이유 개인 공부를 위해 그대로 참고 하였습니다.

Last updated

Was this helpful?