FE (Front End) (구)/javascript

중급 기본 정리 (with 앙마코딩) promise 2탄 async, await

B_Tae 2022. 3. 20. 14:40

이 글은 인프런에서 앙마코딩님의 무료 강좌를 학습한 내용입니다. (자바스크립트 중급 강좌)
문제 시 바로 삭제하겠습니다.

출처 [무료] 자바스크립트 중급 강좌 대시보드 - 인프런 | 강의 (inflearn.com)

async, await

asyncawait를 사용하면 .then을 이용한 체인 형식보다 가독성이 좋아진다.

async

saync를 함수 앞에 작성하면 그 함수는 항상 Promise를 반환한다.
만일 함수 내에 Promise가 있다면, 내부에 있는 Promise를 반환한다.

async function Name(){
  return 'Btae'; // Promise가 없지만 반환은 Promise를 반환
}

Name().then((name) => {
  console.log(name);  // 'Btae'
});

이렇게 사용할 수 있다. then을 사용할 때에도 기본 Promise에서는 변수에 할당하여 사용했지만, async를 사용하면 함수를 사용하고 then을 사용할 수 있다.

앞서 말했듯 함수 Name에 return값이 Promise.resolve('tom');으로 바뀐다면, 내에 있는 Promise를 반환해 'tom'이 반환된다.

또한 마찬가지로 함수내에 오류가 발생하면 reject 값을 반환한다. 당연히 받을 때에는 then이 아닌 catch를 동일하게 사용하면 된다.

await

해석 그대로 값을 기달렸다 실핼 할 때 사용한다. ( 좋은 설명 방법이 떠오르지 않는다.)
예시를 들어 설명해보자

function getName(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(name);
    }, 1000);
  }});
}

async function showName() {
  const result = await getName('Btae'); // await 사용
  console.log(result);
}

showName();

showName() 함수를 실행하면, getName()함수를 실행 시키고 값을 기달렸다 result에 할당하게 된다.
그래서 위 코드에서는 result에 할당되는데 1초가 걸리고 결과적으로 console.log도 1초를 기달렸다 실행된다.

주의할 점await를 사용하기 위해서는 꼭 async로 작성된 함수에만 사용할 수 있다는 점이다.



const f1 = (message) => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res('1번 주문 완료');
    },1000);
  });
};

const f2 = (message) => {
  console.log(message);
  return new Promise((res, rej) => {
    setTimeout(() => {
      res('2번 주문 완료');
    },1000);
  });
};


/* f3 함수 생략 f2와 구조 동일 */

f1()
  .then((res) => f2(res)) // f1 함수는 promise 함수를 반환하고 res값을 f2 message에 넘기는 과정
  .then((res) => f3(res)) // 마찬가지로 f3 message에 넘기는 과정 
  .then((res) => console.log(res)); // 더 넘길 함수가 없다.
  .catch(console.log)
  .finally(() => {
    console.log("끝");
  });

1탄에서 정리했던 Promise이다.

여기서 f1().then 부분의 코드를 async , await를 다른 방법으로 표현 할 수 있다.

async function order() {
  const result1 = await f1();
  const result2 = await f2(result1);  
  const result3 = await f3(result2);
  console.log(result3); 
}
order();

이렇게 구조를 바꿀 수 있고, 위 코드에는 catch나 finally를 표현하지 않았는데 표현해본다면

async function order() {
  try{
      const result1 = await f1();
      const result2 = await f2(result1);  
      const result3 = await f3(result2);
    console.log(result3);
  } catch (e){  // catch
    console.log(e);
  }
  console.log('종료'); // finally
}
order();

위 예제처럼 try{}catch{}을 통해 에러가 났을 때 표현 할 수 있고, 마지막 finally는 별도의 구분 없다.
일반적인 함수처럼 다른 실행 여부와 관련 없이 실행 할 수 있도록 작성하면 된다.


이 구조에서도 순차적으로 실행되기 때문에 에러를 만나게되면 그 전까지 만난 함수의 값은 반환하고 에러 이후에 함수는 실행하지 않는다.
또한 마찬가지로 Promise.all을 사용하여 병렬 실행이 가능하다.
(동시에 시작해서 동시에 결과를 반환한다. 하나라도 에러일 경우 값을 받지 못하는 것도 동일하다.)