TIL 21 JavsScript - Promise

Leo·2021년 4월 26일
0

Javascript

목록 보기
7/17
post-thumbnail

동기식 처리

동기식 처리 모델(Synchronous processing model)은 작업을 직렬적으로 수행한다. 작업이 순차적으로 진행되며 하나의 작업이 수행 중이면 다음 작업은 대기한다.
예를 들어 서버에서 데이터를 가져와 화면에 표시하는 작업을 수행할 때 서버에 데이터를 요청하고 데이터가 응답될 때까지 다른 작업들은 실행되지 않는다.

비동기식 처리

비동기식 처리 모델(Asynchronous processing model)은 작업을 병렬적으로 수행한다. 동기식과 반대로 작업이 순차적으로 진행되지 않고 하나의 작업이 시작되고 다음 작업들이 실행된다. 위의 예시와 같은 상황, 서버에서 데이터를 가져와 화면에 표시하는 작업을 수행할 때 서버에 데이터를 요청하고 응답이 오기 전까지 대기하지 않고 즉시 다음 작업을 수행한다.

비동기식 처리 모델은 요청을 병렬로 처리하여 다른 요청이 블로킹(작업 중단)되지 않는 장점이 있다. 하지만 비동기 처리를 위해 콜백 함수를 사용하다보면 처리 순서를 보장하기 위해 여러 개의 콜백 함수가 중첩되어 콜백 지옥(Callback Hell)이 발생할 수 있는 단점이 있다.

step1(function (value1) {
    step2(function (value2) {
        step3(function (value3) {
            step4(function (value4) {
                step5(function (value5) {
                    step6(function (value6) {
                        // Do something with value6
                    });
                });
            });
        });
    });
});

What Promise?

프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다. 위에서 비동기처리 방식과 동기처리 방식에 대해 알아 본 이유가 비동기 처리에 사용되기 때문이다. 그리고 Promise는 3가지의 상태가 존재한다.

  • pending(대기상태) : 비동기 처리 작업이 아직 완료되지 않은 상태
  • fulfilled(완료상태) : 비동기 처리가 완료되어 값을 반환 해준 상태
  • rejected(실패상태) : 비동기 처리가 실패하거나 오류가 발생한 상태

생성자를 이용해 new Promise()로생성해야하고, 생성된 후 대기상태로 머무른다. 그리고 콜백 함수 인자로 resolve, reject를 사용할 수 있다. 성공하면 resolve에 결과값을 넣어 반환하고 실패하면 reject에 에러 처리를 할 수 있다.

pending(대기상태) : new Promise()를 호출하면 대기 상태가 된다.

new Promise();

호출 : 대기상태의 Promise()는 콜백함수를 인자(resolve, reject)로 받을 수 있다.

new Promise(function(resolve, reject) {
  // ...
});

fulfilled(완료상태) : resolve를 실행하면 완료 상태가 된다.

new Promise(function(resolve, reject) {
  resolve();
})

완료 상태의 결과 처리 : 완료 상태가 되면 then()을 사용해 결과값을 받을 수 있다.

function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

rejected(실패상태) : reject를 실행하면 실패 상태가 된다.

new Promise(function(resolve, reject) {
  reject();
})

실패 상태의 결과 처리 : 실패 상태가 되면 실패 상태를 처리 한 값을 catch()로 받을 수 있다.

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Error!!"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error!!
});

Why Promise?

프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용된다. 웹 애플리케이션에서 서버에서 데이터를 요청하고 받기 위해 API(ex. Ajax, fetch())를 사용한다.

$.get('url 주소/products/1', function(response) {
  // ...
});

위 예시는 Ajax를 사용한 코드인데 실행 시 데이터 요청을 보낸다. 그런데 여기서 데이터를 받아 오기 전에 .map()이나 .forEach()같은 메서드를 사용해서 배열을 사용하려고 하면 에러가 난다. 빈 배열인데 map메서드를 사용하려 해서 그런 것이다. 프로젝트 진행 시 배열에 .map()를 사용하는데 데이터가 없는데 .map()를 사용하면 에러가 나는 경우가 이런 것이었다. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스이다.

정리

리액트 공부 중, fetch()함수를 사용하면 Promise객체를 반환한다고 알고 있었다. 하지만 Promise객체가 결국 무엇인지 몰랐는데 정리를 하면서 조금은 이해가 된 것 같다. react로 결국 자바스크립트 확장문법이기 때문에 자바스크립트를 Deep하게 공부해야 더 도움이 될 것 같다.

profile
느리지만 확실하게

4개의 댓글

comment-user-thumbnail
2021년 4월 27일

데이터를 받아 오기 전에 데이터를 받아오면 오류가 난다 이게 뭔말인가여>?

1개의 답글
comment-user-thumbnail
2021년 4월 27일

API 요청 예제코드를 fetch, Axios로 정리하셔야 좋을거 같은데요

1개의 답글