promise, async/await가 뭘까?

권세진·2021년 2월 18일
2

js이론

목록 보기
3/9

@ 잘 써보지 않았던 async/await, promise 구문이 나와서
헷갈리는 부분을 정리하기 위해 글을 작성합니다 😊

@ 이 게시물에서는 각 구문들이 생겨나게 된 배경에 따라 시간 순으로 작성하겠습니다.

🤙 promise

promise는 비동기 작업의 완료나 실패를 나타내는 객체입니다.

promise의 배경

promise는 어떻게 생겨나게 되었을까
이를 보려면 이전에 2개 이상의 비동기 작업의 처리 방식을 보아야 합니다.

setTimeout(() => {
  const result = 1;
  setTimeout(() => {
    const result2 = 2;
    setTimeout(() => {
      console.log(result, result2);
    },700);
  },600);
},500);

위의 코드는 하나의 비동기 작업이 처리되면 다음 비동기 작업을
처리하도록 만들어진 코드입니다.
위와 같이 이전에는 2개 이상의 비동기 작업에 대한 처리를 하려면
지옥의 콜백 피라미드 현상이 일어나곤 했습니다.

이와 같은 작업의 처리를 좀 더 간편하게 하기 위해
promise가 탄생했습니다.

new Promise((resolve) => {
  setTimeout(() => resolve(1), 500);
})
.then((result) => {
  return new Promise((resolve) => {
    setTimeout(() => resolve([result, 2]), 600);
  });
})
.then((result) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(result.join());
      resolve(result.join());
    },700)
  });
});

좀 더 깔끔해지지 않았나요?
promise는 이런 요구에 맞춰 등장하게 되었습니다.

promise는 setTimeout보다 우선순위가 높다.

promise는 일반 테스크 큐에 저장되지 않고
마이크로 테스크 큐(일반 테스크 큐보다 우선순위 높음)에 저장되어
일반 비동기 함수보다 일찍 실행됩니다.

개인적인 의견으로는
promise는 개발자가 커스텀하게 만들 수 있고
비동기 작업의 완료나 실패를 나타내는 객체라
다른 비동기 작업을 관리하기 때문에 우선순위가 높은 것 같습니다.
(웹 api에서 제공하는 비동기 함수는 일반 테스크 큐에 저장됨)

🤔 async/await

async/await는
promise를 동기적인 코드처럼 작성할 수 있게 하는 문법입니다.

async/await의 배경

promise를 사용하다가 이제는
비동기 코드를 일반적인 동기 코드 처럼 작성하고 싶은 요구가 생겨났습니다.
그렇게 만들어진 것이 async/await 입니다.
1. 기존의 promise 코드

function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url) // returns a promise
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}
  1. async/await로 작성한 코드
async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url);
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

async/await의 특징

  • await는 반드시 async function 내부에서만 사용이 가능합니다.
  • await 이후에는 반드시 promise 객체만이 와야합니다.
  • async function 내에 await 구문이 없을 시 일반 동기 함수 처럼 동작합니다.
  • (중요)항상 리턴값은 암묵적으로 Promise 객체에 의해 감싸져 리턴됩니다.

예시)

async function foo() {
  await 1;
  //undefined가 promise로 감싸져 리턴
}

위 코드는 아래와 같음

function foo() {
  //undefined가 promise로 감싸져 리턴
  return Promise.resolve(1).then(() => undefined)
}
  • (중요) await new Promise(...) 는 프라미스를 해체하여 실제 값을 가져옵니다.
async function getBody() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts/1'); // return Promise
  const body = await response.json();
  console.log(body, 1); //output: 객체
  return body; //자동으로 프라미스로 감싼다.
}

async function aa() {
  console.log(getBody(), 2); //output: 프라미스
  console.log(await getBody(), 3); //output: 객체
}

aa();

참조

mdn page

ystone님의 벨로그

profile
상상을 현실로 꺼내길 좋아하는 프론트엔드 개발자입니다.

2개의 댓글