프론트엔드 개발/JavaScript

자바스크립트) Promise 쓰기 귀찮을 땐 async, await

Ella Seon 2022. 11. 29. 14:36

0. async / await

- ES8 에서는 비동기 처리를 동기 처리처럼 동작하도록 구현할 수 있는 async/await 이 도입되었다.

- async/await는 프로미스를 기반으로 동작하기 때문에 프로미스의 then/catch/finally 등의 후속 처리 메서드에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리할 필요 없이 마치 동기 처리처럼 프로미스를 사용할 수 있다.

 

🔸Promise 기존 코드

function 함수(){
  return new Promise((resolve,reject)=>{
    resolve('안녕')
  })
}


함수()
.then(n=>console.log(n))  // 안녕

 

async 변환 코드

- async로 변환한 코드는 굳이 new Promise()로 붙여서 쓸 필요가없다. 

- 왜냐? async를 붙인 함수 자체가 Promise가 되기 때문이다. 즉, async 함수는 언제나 프로미스를 반환한다.

- async는 function 선언 앞에만 붙일 수 있다.

- 함수2를 콘솔창에 출력해보면 Promise가 반환되는 것을 볼수있다. 

- 따라서, 함수2() 뒤에는 .then을 붙일수가 있다. 

async function 함수2(){
return '잘가'
}

console.log(함수2()) //Promise {<fulfilled>: '잘가'}

함수2()
  .then(n=>console.log(n)) //잘가

 

- 물론 async 안에 new Promise를 붙여도 상관없다.

    async function 함수3() {
      return new Promise((resolve,reject)=>{
        resolve('안녕하세요')
      })
    }

    함수3()
      .then(n => console.log(n)) //안녕하세요

🔸async 다른예제 (함수안에서 연산한 결과를 then 안에서 사용하고 싶다면)

async function 더하기(){
  return 1 + 1 
}

더하기().then(function(결과){
  console.log(결과) //2
});

 

then 쓰기 귀찮다면 await을 쓰자

- await 키워드는 프로미스가 settled 상태(비동기 처리가 수행된 상태)가 될 때까지 대기하다가 settled 상태가 되면 프로미스가 resolve 한 처리 결과를 반환한다.

- await 키워드는 반드시 프로미스 앞에서 사용해야한다.

 

🔸await 쓰는 순서

 

1)  await은 async함수 안에서만 동작한다. 

따라서, then을 먼저 async함수 밖이 아닌 안에다가 적어준다.

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    var 결과 = 1 + 1;
    성공();
  });
  어려운연산.then();
}
더하기();

 

2) 그리고 promise객체 앞에 await을 붙어준다.

await은 Promise가 완료될때까지 기다린다.

await은 Promise가 resolve 즉, 성공한 값을 내놓는다.

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    var 결과 = 1 + 1;
    성공();
  });
  var 결과 = await 어려운연산;
}
더하기();

3) 결과값을 콘솔창에 출력하고 싶으면 성공함수에 parameter를 담아주면 된다.

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    var 결과 = 1 + 1;
    성공(결과);
  });
  var 결과 = await 어려운연산;
  console.log(결과);
}
더하기(); //2

await은 실패하면 에러가 나고 코드가 멈춘다.

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    실패();
  });
  var 결과 = await 어려운연산;
  console.log(결과);
}
더하기();

 

Promise가 실패할경우 try,catch를 쓰면된다.

- try{} 안의 코드가 에러가 나고 멈출 경우, catch{} 내부의 코드를 실행해준다. 

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    실패();
  });
  try {  var 결과 = await 어려운연산 }
  catch { 어려운연산 Promise가 실패할 경우 실행할 코드 }
}

 

🔸async/await 예제코드

<body>
  <pre></pre>
  <script>
    // async 사용!
    async function fetchTodo() {
      const url = "https://jsonplaceholder.typicode.com/todos/1";

      const response = await fetch(url);
      const todo = await response.json();
      console.log(todo);
      const result = JSON.stringify(todo, null, 2);
      document.querySelector("pre").innerHTML = result;
      // {userId: 1, id: 1, title: 'delectus aut autem', completed: false}
    }

    fetchTodo();
  </script>
</body>
async function foo() {
  const a = await new Promise((resolve) => setTimeout(() => resolve(1), 3000));
  const b = await new Promise((resolve) => setTimeout(() => resolve(2), 2000));
  const c = await new Promise((resolve) => setTimeout(() => resolve(3), 1000));

  console.log([a, b, c]); // [1, 2, 3]
}

foo(); // 약 6초 소요된다.

1. Promise 와 async/await 차이점

① 에러 핸들링
- Promise 를 활용할 시에는 .catch() 문을 통해 에러 핸들링을 해야 하지만,
- async/await 은 try / catch를 통해 에러를 처리할 수 있다


② 코드 가독성
- Promise의 후속 처리 메서드인 .then() 의 hell의 가능성
- async/await 은 프로미스의 후속 처리 메서드 없이 마치 동기 처리처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있기 때문에 코드 흐름을 이해 하기 쉽다.


출처

https://velog.io/@khyup0629/javascript-async%EC%99%80-await%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%82%AC%EC%9A%A9%EB%B2%95

 

[javascript] async와 await의 개념과 사용법

자바스크립트는 싱글 스레드 프로그래밍 언어이기 때문에 비동기 처리가 기반입니다. 비동기 처리는 그 결과가 언제 반환될 지 알 수 없기 때문에 동기식으로 처리하는 기법들이 사용되어야 하

velog.io

코딩애플 Promise 어려워서 싫으면 async/await을 사용합시다.

https://ko.javascript.info/async-await