Promise(then, catch)

isthis·2022년 3월 16일
0

Promise

목록 보기
2/5
post-thumbnail

동기/비동기

Promise에 대해 공부하기 전, 동기와 비동기에 대해 먼저 알아보자.

Synchronous는 동기라고 하고, Asynchronous는 비동기라고 부른다.
동기는 다양한 명령을 실행시켰을 때, 순차적으로 실행되는 것이다.
반면, 비동기는 다양한 명령을 실행을 시켰을 때, 본인의 시간표에 따라 동시에 각자 실행되는 것이다.

동기적인 방법은 순서대로 실행되기 때문에 어떻게 실행되는지 파악하기 쉬운 반면,
비동기적인 방법은 동시에 여러가지 일을 하기 때문에 혼란스러우나, 훨씬 더 빠르게 실행시킬 수 있다.

그렇다면, 비동기적인 실행을 하는 경우는 언제일까?

  1. 명령이 언제 끝날지 예측하기 어려운 경우
  2. 주가 되는 작업이 아닐 경우

대표적인 예로, 서버 통신을 들 수 있다. 서버 통신은 언제 끝날지 예측하기 어렵다. 인터넷이 느릴 수도 있고, 서버가 느릴 수도 있기 때문이다.
따라서, 통신을 하는 동안 다른 작업을 하고 있다가 통신이 끝났을 때 콜백을 호출하면서 필요한 작업을 나중에 수행한다.
네이버 검색을 예로 들어보자. 네이버에서 검색창에 글자를 입력하면 브라우저와 서버는 통신을 하게 된다.
그 동안 우리는 아무것도 할 수 없나? 그렇지 않다. 대부분 통신을 한다는 것 조차 알아차리지 못한다. 이처럼 비동기적으로 통신을 했기 때문이다.

이제 웹 브라우저와 웹 서버가 통신할 때 사용하는 fetch api를 살펴보자. fetch api는 Promise를 사용한다.
이를 통해 Promise를 다루는 방법을 알아보자.


Promise

fetch('https://jsonplaceholder.typicode.com/posts')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
  });

위 코드는 링크로 요청을 보내서, myJson 파라미터를 통해 웹서버가 반환해준 json data type을 javascript data type에 맞게 컨버팅한 결과를 가져올 수 있는 코드다.

MDN에서 fetch에 대해 살펴보자. 위 사진을 보면, Promise를 반환한다고 적혀있다. 또한, 그 Promise data type은 Response object를 반환할 것이라 되어있다.(정확히는, Response 객체로 확인할 수 있는 Promise)

직접 확인해보자.

fetch로 받은 결과를 fetched라는 변수에 저장했다. 그 후, 출력해보니 Promise라는 data type을 반환하고 있다. 여기서 알아야 할 것이 두 가지가 있다.

  1. 이처럼, 어떠한 함수의 반환 값이 Promise일 경우 해당 함수는 비동기적으로 동작하는 함수일 가능성이 매우 높다.
  2. 그 함수가 반환한 값(Promise)은 추가로 두 개의 함수(메서드)를 사용할 수 있다.

2번에 대해 조금 더 얘기를 해보자면, then과 catch라는 함수를 사용할 수 있다. 두 가지 함수 모두 콜백 함수를 받는다. 그리고, 둘 다 파라미터를 하나씩 가지고 있다.
then은 fetch를 통해 실행한 결과가 성공했을 때, then으로 전달된 콜백 함수가 호출되도록 되어있다. 그리고, 콜백 함수가 실행되면서 fetch에서의 결과값이 있다면, 첫 번째 파라미터로 받게 된다.
catch는 fetch를 통해 실행한 결과가 실패했을 때의 경우이며 then과 마찬가지로 동작한다. 대신, 파라미터에는 결과값 대신 실패한 이유가 담겨있다.

< fetch 성공 후 then 메서드 예시 >

< fetch 실패 후 catch 메서드 예시 >

Promise를 사용하는 이유

비동기적인 작업을 처리할 때, 작업의 성공 유무에 따라 표준화된 방식(then, catch)으로 처리할 수 있게 해주기 때문이다.

지금까지의 내용을 정리하면, 위의 사진처럼 코드를 작성할 수 있다.
위 코드의 response에는 응답 결과, url 등 다양한 값이 포함되어 있다. 문제는 보내준 값을 그대로 받아온다. 따라서, 일반 json text로 인식하기 때문에 받아온 값을 사용하기가 쉽지 않다. 이럴 때는 값을 자바스크립트 data type으로 변경해주어야 하는데, response.json(), response.text() 등을 사용할 수 있다. 이번에는 json type data를 받았기에 response.json()을 사용하였고, 해당 메서드에 대한 설명은 다음과 같다.

💡 response.json() 메서드란?
본문 텍스트를 JSON으로 구문 분석한 결과를 확인할 수 있는 Promise를 반환합니다. 메서드 이름이 json()임에도 불구하고 결과는 JSON이 아니라 JSON을 입력으로 사용하고 이를 구문 분석하여 JavaScript 객체를 생성한 결과입니다.

response.json()으로 값을 받아오니 Promise로 반환된 것을 확인할 수 있다.

response.json()의 결과값은 Promise이므로, then을 사용할 수 있다. then을 사용하여 받아온 파라미터를 출력한 결과는 위 사진과 같다. 확인해보면, 자바스크립트의 data type으로 변경된 것을 확인할 수 있다. 이를 활용하여 다양한 작업을 수월하게 진행할 수 있게 되었다.

하지만, Promise를 위 사진처럼 사용하진 않는다. 위 사진은 then 안에 then이 들어가고, 또 then 안에 then이 들어간다. 이런 방식을 Nested promise(네이스트 방식)이라고 한다.
일반적으로는 다음 사진과 같이 Promise를 사용한다.

위 방식은 then 안에서 promise를 return한다. 이렇게 하면, 바깥 쪽에서 then과 then을 연결할 수 있다. 이러한 방식을 promise chaining(체이닝 방식)이라고 한다.

둘 다 장단점이 있으나, 체이닝 방식을 일반적으로 사용하고, 더 깔끔한 느낌을 준다.


정리

Promise 동작 과정

  1. Promise를 사용하게 되면 그 즉시 Pending 상태(대기/진행 중인 상태)가 된다.
  2. 결과가 성공하면 then으로 전달된 콜백 함수가 호출된다.
  3. 에러가 발생하면 catch 안으로 전달된 콜백 함수가 호출된다.
  4. then 또는 catch에서 새로운 Promise를 return하면 또 다시 Pending 상태가 되며 반복된다.

Promise 특징

  • Promise는 비동기적인 작업 처리를 위한 도구이다.
  • Promise는 then과 catch로 사용할 수 있다.
  • Promise를 반환하는 함수 자체는 동기적으로 실행되며, Promise를 반환하는 함수일 경우 비동기적으로 처리된다.
  • 비동기적인 작업을 처리할 때, 작업의 성공 유무에 따라 표준화된 방식(then, catch)으로 처리할 수 있게 해주기 때문에 사용한다.
  • 네이스팅 방식과 체이닝 방식이 있으며, 일반적으로 체이닝 방식을 사용한다.

참고자료
생활코딩

profile
공부

0개의 댓글