맨 땅에 프론트엔드 개발자 되기

Promise, Fetch, Async, Await 에 대해 알아보자 본문

코딩 공부 일지/JavaScript

Promise, Fetch, Async, Await 에 대해 알아보자

헬로코딩 2022. 3. 15. 11:23
728x90

Promise, Fetch, Async, Await 에 대해 알아보자

 

Promise

 

Promise는 JavaScript의 비동기 처리에 사용되는 객체로써 비동기로 처리되는 결과를 동기처럼 반환한다. 실제로 동기처럼 처리되는 것이 아니라 미래의 데이터 처리가 완료된 시점에 결과를 제공하겠다는 ‘약속(프로미스)’를 반환한다.

 

- Promise 객체를 사용하는 이유

JavaScript에는 동기 작업과 비동기 작업이 있는데, 비동기로 처리되는 작업의 결과를 사용하기 위해 Promise 객체를 사용한다. 비동기 작업이 끝난 후의 결과를 이용해서 작업을 수행하려면 Promise 객체의 콜백함수로 작업을 지정해줘야 한다. 그래야 ‘순서를 보장’ 받을수 있다. 이러한 콜백함수가 너무 많아지면, 수정이 복잡해지고 코드의 가독성도 떨어지게 되는데 이를 ‘콜백지옥’이라고 한다.

콜백지옥을 방지하기 위해 then()을 이어붙여 콜백함수 작업을 처리할 수 있도록 만들 수 있다.

 

 

JavaScript 동기와 비동기, 콜백함수

JavaScript 동기와 비동기, 콜백함수 JavaScript를 공부하다보면 자주 듣게 되는 용어인 ‘동기’와 ‘비동기’. 한자어로 되어 있어서 직관적으로 무슨 뜻인지 알기가 어려운데, 알고보면 쉽기도 하

babycoder05.tistory.com

 

Promise 예제

function getData() {
    return new Promise((resolve, reject) => {
	// 비동기작업
      fetch('데이터url', (response) => {
        resolve(response)
      })
    })
  }

 getData()
 .then(data => {
    console.log(data)
  })
.catch(err => {
    console.log(err)
  })

 

Promise 작업의 결과는 resolve와 reject로 받을 수 있는데, Promise 작업이 성공했을 때는 resolve로 어떤 이유로 실패했을 때는 reject로 받는다.

 

Fetch

 

Fetch는 JavaScript 내장 API로 비동기 통신 네트워크를 가능하게 하는 기술이다. 비교적 최근에 나온 기술로 XMLHttpRequest 보다 훨씬 간단하고 보기에도 간결하다. jQuery.ajax()와도 비슷하지만 요즘 jQuery를 잘 안 쓰는 추세이므로, Fetch가 훨씬 많이 쓰이는 것 같다.

위의 Promise 예제처럼 new Promise 객체를 만들기보다 아래 예제와 같이 사용되는 사례가 많다. fetch 함수는 url로 요청을 보낸 결과로 Promise 객체를 반환한다.

 

Fetch 예제

fetch('데이터url')
  .then(response => {
    return response.json()
  })
  .then(data => {
    console.log(data)
  })
  .catch(err => {
    console.log(err)
  })

 

- Fetch의 특징

  • Fetch로 반환되는 Promise 객체는 error를 reject 하지 않는다. 대신 ok 상태가 false인 resolve가 반환된다. 그러므로 reject를 이용하지 않고, 별도로 에러처리를 해주어야 한다.
  • Fetch는 쿠키를 보내거나 받지 않는다. 쿠키를 전송하기 위해서는 자격증명(credentials) 옵션을 설정해주어야 한다.

 

async & await

 

async와 await은 비동기 처리 API 중에 가장 최근에 도입된 문법으로 기존의 불편함을 보완하기 위해 나온 편리한 구문(Synthetic Sugar)이다. async와 await을 사용하는 이유를 알기 위해 다음의 코드를 보자.

 

function callAsync() {
    const data = fetch('데이터url')
    
    if(data.id === 1) {
      console.log(data.name);
    }
  }

 

위와 같은 함수가 있다고 할 때 콘솔창에는 과연 무엇이 나올까? fetch는 비동기로 동작하기 때문에 콘솔창의 결과는 장담할 수가 없다. 콜백함수로 처리해야만 결과를 보장받을 수 있다. 이의 단점을 보완하기 위해 등장한 것이 async와 await 이다.

위의 코드를 동작하게 하려면 아래와 같이 async와 await을 붙여주면 된다.

 

async & await 예제

async function callAsync() {
    const data = await fetch('데이터url');

    if(data.id === 1) {
      console.log(data.name);
    }
  }

 

async라고 비동기 함수를 선언해주고, 비동기 작업에 await를 붙여주면 그 뒤에 이 결과를 사용하는 작업에서 동기처럼 처리가 된다. 즉, 비동기 작업이 이루어진 후에 그 결과로 작업이 수행된다.

 

- async & await 예외처리

Promise 객체의 예외처리는 메소드 체이닝(Chaining)으로 catch() 메소드를 이어붙이면 됐었다. 그러나 async & await은 그렇게 예외처리를 할 수가 없다. 대신, try catch 구문을 이용해서 한다.

 

async & await 예외처리 예제

async function callAsync() {
    try{
      const data = await fetch('데이터url');

      if(data.id === 1) {
        console.log(data.name);
      }
    } catch (err) {
      console.log(err)
    }
  }

 

결론

1. Promise 객체는 비동기 작업의 결과로 메소드 체이닝을 통해 then() / catch()를 이어붙여서 콜백함수를 대신할 수 있다.

2. async & await은 아예 비동기 작업을 동기적인 것처럼 만들어서 콜백함수 대신 동기적으로 코드를 작성할 수 있다.

3. 상황에 따라 맞는 방법을 택하자.

4. 그러나 또 이를 보완한 새로운 기술이 등장할 수 있다는 점을 명심하자...

728x90