[JS] async/await 엿보기

sjoleee·2022년 4월 3일
0

promise에 이어 async/await에 대해 기록하고자 한다.

  • asyncpromise 대신 사용
    • 단, async성공/실패를 나눌 수 없다
  • awaitthen 대신 사용

으로 간단하게 정리하고자 한다.

  • function 선언 앞에 async 키워드를 사용할 수 있다.
  • async 키워드는 promise 객체를 반환한다.

그러니까 new Promise 어쩌구 할 필요 없이,
함수를 선언하면서 앞에 async 키워드만 달아주면 함수 자체가 Promise가 된다.

이제 순차적으로 실행하고 싶을 때, 콜백함수 대신 promise, promise대신 async라고 내맘대로 이해하겠다.(아님말고)


기존 Promise를 사용하던 방식이 이런 형태

const promise = new Promise((resolve, reject) => {
  let 연산 = 1 + 1;
  resolve();
});

promise.then(() => {
  console.log("성공");
});

이렇게 하면 연산이 성공할 경우(무조건 성공하게 해놨다), '성공'이 출력된다. 이제 `async`를 사용해보자.
async function plus() {
  let 연산 = 1 + 1;
  return "성공";
}

plus().then((결과) => {
  console.log(결과);
});

plus 함수가 Promise가 되므로 then을 사용할 수 있고, 동일하게 '성공'을 출력한다.
그런데, 성공/실패를 판정하지는 못한다.

이번에는 plus 함수 안에서 연산을 하는데, 성공/실패를 판정해보겠다.

async function plus() {
  const promise = new Promise((resolve, reject) => {
    let 뭔가 = 1 + 1;
    resolve();
  });

  promise.then(() => console.log("성공"));
}

plus();

이렇게, 뭔가를 성공/실패했는지 판정하기 위해서 promise를 plus함수 안에 만들었고, 성공할 경우(then) '성공'을 출력하도록 만들었다.

이번에는 then을 대체할 await를 사용해보자.
await는 async 안에서만 사용 가능하다.

async function plus() {
  const promise = new Promise((resolve, reject) => {
    let 뭔가 = 1 + 1;
    resolve("성공");
  });

  let result = await promise;
  console.log(result);
}

plus();

솔직히 then에 비해 await가 더 편한 이유를 잘 모르겠다. 이게 막 then을 길게 사용할 때 느끼게 된다는데, 써본 적이 없어서...

어쨌든, 이렇게 await를 사용한다.

await는 '기다려라'는 뜻이다.
위 경우, promise가 완료되기를 기다려라는 뜻.
그래서 promise가 오래 걸리는 작업이라면, 코드 실행이 await에서 그만큼 멈춘다.
만약 실패하는 경우에는 await에서 에러가 나고 코드가 멈춘다.

에러나고 멈추게 코드를 짜보자,

async function plus() {
  const promise = new Promise((resolve, reject) => {
    let 뭔가 = 1 + 1;
    reject();
  });

  let result = await promise;
  console.log(result);
  console.log("멈췄니?1");
  console.log("멈췄니?2");
  console.log("멈췄니?3");
}

plus();

이 경우, 멈췄니?라고 물어봐도 아무 것도 출력되지 않는다.
실패하는 경우에도 코드가 멈추지 않게 하려면 try/catch 구문을 사용하면 된다.

try{a} catch{b}

a 해보고 실패하면 b 해달라는 뜻.
위의 경우에 대입해보자.(실패하는 경우로 수정해서)

async function plus() {
  const promise = new Promise((resolve, reject) => {
    let 뭔가 = 1 + 1;
    reject();
  });

  try {
    let result = await promise;
  } catch {
    console.log("실패했어요");
  }
}

plus();

이렇게 에러처리가 가능하다.


아래는 버튼을 클릭하면 '성공'을 출력하는 Promise 만들기다.

const btn = document.getElementById("button");

const promise = new Promise((resolve, reject) => {
  btn.addEventListener("click", () => {
    resolve();
  });
});

promise.then(() => {
  console.log("성공");
});

이렇게도 만들어 보고,

const btn = document.getElementById("button");

async function btnClick() {
  const promise = new Promise((resolve, reject) => {
    btn.addEventListener("click", () => {
      resolve("성공");
    });
  });
  let 결과 = await promise;
  console.log(결과);
}

btnClick();

이렇게도 만들어 봤다.

근데 이렇게 만들면 안되더라.

const btn = document.getElementById("button");

async function btnClick() {
  btn.addEventListener("click", () => {
    return "성공";
  });
}

async function btnClick2() {
  let 결과 = await btnClick();
  console.log(결과);
}

btnClick2();

안되는 이유는,

  1. 이벤트 리스너안의 코드는 바로 실행되지 않습니다. 버튼 누를 때 실행됩니다.
  2. 그래서 컴퓨터가 코드를 쭉 읽을 때 async function 프로미스() 함수 내부는 빈칸과 동일합니다.
  3. 자바스크립트는 function 안이 빈칸이면 그냥 자동으로 return undefined 를 채워 실행합니다.

btnClick는 곧바로 undefined로 처리된다.
그러므로 결과가 undefined

끗.

profile
상조의 개발일지

1개의 댓글

comment-user-thumbnail
2022년 4월 3일

좋은 글 감사합니다. synchronous 한 프로그래밍에 익숙하여, async를 이해하는데 어려움이 많은데요 *^^ 글보고 이해가 잘 되네요

답글 달기