본문 바로가기

Frontend/JavaScript

2020-05-21 :: Promise

Promise는 ECMASCript 6부터 추가되었다. 비동기 처리를 작성하다 보면 콜백 함수가 중첩되어 알아보기 어려운 코드가 만들어진다. 이때 Promise를 사용하면 복잡하게 중첩된 코드를 더욱 알아보기 쉽게 작성할 수 있다.

비동기 처리의 예

setTimeout이나 addEventListener 메서드는 비동기적으로 실행된다. 하지만 이들을 다루는 코드는 보통 순차적으로 실행되지 않는다.

console.log("A");
setTimeout(function() {console.log('B'); }. 0};
console.log("C");

위와 같은 코드의 실행결과는 A C B가 된다. setTimeout 함수로는 인수로 받은 콜백 함수를 일정 시간이 흐른 후에 실행하도록 예약하는 처리만 하고, 그다음 곧장 다음 코드가 실행되기 때문이다. 호출 스택에 실행 문맥이 남아 있을 때는 그 작업이 끝날 때까지 기다렸다가 0초 후에 가능한 한 빨리 실행된다.

하지만 실행 순서가 중요한 상황이 있다. 이러한 상황에서 코드를 실행 순서에 따라 실행하고자 할 때는 콜백 함수를 중첩하는 방법을 사용한다. 예를들어 네트워크 통신을 통해 데이터를 받아오고 그 데이터를 특정 순서에 따라 가공하는 경우.

function sleep(callback) {
   setTimeout(function(){
      callback();
   }, 1000);
}

sleep(function() {
   console.log('A');
   sleep(function() {
      console.log('B');
      sleep(function() {
         console.log('C');
      });
   });
});

하지만 콜백 함수가 여러개 중첩되면 위와 같이 작업 내용을 이해하기 어려워진다. 이를 '콜백 지옥'이라고 부른다. 이러한 상황을 해결하기 위해 등장한 것이 Promise이다. Promise를 사용하면 이 문제를 해결할 수 있고 비동기 처리도 더욱 간결하게 작성할 수 있다.

Promise의 기본

Promise는 비동기 처리를 실행하고 그 처리가 끝난 후에 다음 처리를 실행하기 위한 용도로 사용한다. Promise를 사용하려면 먼저 Promise 객체를 생성해야 한다. Promise 생성자의 사용법은 다음과 같다.

let promise = new Promise(function(resolve, reject) { ... });

promise에 실행하고자 하는 처리를 작성한 함수를 인수로 넘긴다. 그리고 이 함수는 다음과 같은 인수를 받는다.

더보기

resolve: 함수 안의 처리가 끝났을 때 호출해야 하는 콜백 함수. resolve 함수에는 어떠한 값도 인수로 넘길 수 있다. 이 값은 다음 처리를 실행하는 함수에 전달된다.

 

reject: 함수 안의 처리가 실패했을 때 호출해야 하는 콜백 함수. reject 함수에는 어떠한 값도 인수로 넘길 수있다. 대부분 오류 메시지 문자열을 인자로 사용한다.

let promise = new Promise(function(resolve, reject) {
   setTimeout(function() {
      console.log('A');
      resolve();
   }, 1000);
});
promise.then(function() {
   console.log('B');
});

이 코드를 실행하면 1초 후에 'A'가 표시되고, 그 다음에 'B'가 표시된다. 위 코드에서 Promise에 인수로 넘긴 함수는 비동기 처리를 수행하는 함수이며, 1초 후에 'A'를 표시하고, 그 다음에는 함수 resolve를 호출해서 Primise 안의 처리를 종료시킨다. resolve 함수가 실행되면 then 메서드에 등록한 함수가 호출된다.

Promise를 종료시키는 resolve 함수와 then 메서드

resolve 함수는 Promise를 종료시킨다. resolve 함수에 인수로 넘긴 값은 then 메서드에 인수로 넘긴 함수에 전달되어 다음 처리를 위해 사용된다. then 메서드의 사용법은 다음과 같다.

promise.then(onFullfilled);

onFullfilled 함수는 성공 콜백 함수라고 하며 promise 안의 처리가 정상적으로 끝났을 때 호출되는 함수이다. onFullfilled 함수는 인수로 response를 받는다. 이것은 promise 안에서 resolve 함수를 실행할 때 넘긴 인수이다.

let promise = new Promise(function(resolve, reject) {
   setTimeout(function() {
      let name = prompt('이름을 입력하세요');
      resolve(name);
   }, 1000);
});
promise.then(function(name) {
   console.log('안녕하세요, ' + name + '님');
});

Promise를 실패로 처리하는 reject 함수와 catch 메서드

reject 함수는 Promise를 종료시킨다. resolve 함수와 마찬가지로 reject 함수에도 값을 넘길 수 있다. reject 함수가 실행되면 then 메서드에 넘긴 함수는 실행되지 않는다. 대신 catch 메서드에 넘긴 함수가 실행된다. catch 메서드의 사용법은 다음과 같다.

promise.catch(onRejected);

onRejected함수는 실패 콜백 함수라고 하며 promise 안의 처리가 실패로 끝났을 때 호출되는 함수이다. 

'Frontend > JavaScript' 카테고리의 다른 글

JEST  (0) 2021.08.31
history, location, match  (0) 2021.07.07
프론트 비동기 작업 이해하기(feat. React)  (0) 2021.07.03
200824  (0) 2020.08.24
200816 DOM  (0) 2020.08.16