[Javascript] 비동기와 Promise

devMag 개발 블로그·2022년 2월 10일
0

Javascript

목록 보기
9/13
post-custom-banner

비동기와 Promise

비동기란?

동기와 비동기

JS는 싱글스레드로 한 번에 하나의 작업만 할 수 있다. 이를 해결하기 위해서 비동기적 기법이 사용된다.
비동기적으로 처리하면 동시에 여러가지 작업을 처리 할 수 있는 방법있으며 기다기면서 다른 함수를 호출할 수 있다.

JS의 대표적인 비동기 처리 사례는 setTimeout() 을 쓰는 것이다.
일정 시간뒤에 함수를 실행시킨다.

console.log("시작")

setTimeout(function() {
  console.log('5초 후 실행합니다.')
}, 5000)

console.log('끝')

// 시작
// 끝
// 5초 후 실행합니다.

위의 코드의 결과는 아래 주석과 같이 나온다.

다음과 같은 작업들은 주로 비동기적으로 처리하게 된다.

  • Ajax Web API 요청: 만약 서버쪽에서 데이터를 받와아야 할 때는, 요청을 하고 서버에서 응답을 할 때 까지 대기를 해야 되기 때문에 작업을 비동기적으로 처리한.
  • 파일 읽기: 주로 서버 쪽에서 파일을 읽어야 하는 상황에는 비동기적으로 처리한다.
  • 암호화/복호화: 암호화/복호화를 할 때에도 바로 처리가 되지 않고, 시간이 어느정도 걸리는 경우가 있기 때문에 비동기적으로 처리한다.
  • 작업 예약: 단순히 어떤 작업을 몇초 후에 스케쥴링 해야 하는 상황에는, setTimeout 을 사용하여 비동기적으로 처리한다.

비동기 작업을 다룰 때에는 콜백 함수 외에도 Promise, 그리고 async/await 라는 문법을 사용하여 처리 할 수 있다.


Promise

이전에는 비동기 작업을 처리 할 때에는 콜백 함수로 처리를 해야 했었다. 콜백 함수로 처리를 하게 된다면 비동기 작업이 많아질 경우 코드가 쉽게 난잡해지게 되었다. 콜백 함수의 error, success의 처리를 보다 간단하게 하기 위해 Promise가 생겼다.

callback hell

비동기적으로 처리해야 하는 일이 많아질수록, 코드의 깊이가 계속 깊어지는 현상이 있는데, Promise 를 사용하면 이렇게 코드의 깊이가 깊어지는 현상을 방지 할 수 있다.


Promise 주로 어디서 왜 필요한가?

Promise는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용하게 된다. 일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아온다. 서버에다가 ‘데이터 하나 보내주세요’ 라는 요청을 보내게 된다. 그런데 여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 Promise이다.

Promise 기초

Promise의 동작을 이해해보자. 먼저 아래 코드는 간단한 ajax 통신 코드이다.

function getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

위 코드는 제이쿼리의 ajax 통신 API를 이용하여 지정된 url에서 1번 상품 데이터를 받아오는 코드이다. 비동기 처리를 위해 프로미스 대신에 콜백 함수를 사용했다.

위 코드에 Promise를 적용하면 아래와 같아진다.

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

콜백 함수로 처리하던 구조에서 new Promise(), resolve(), then()와 같은 프로미스 API를 사용한 구조로 바뀌었다.


Promise의 상태

Promise는 new Promise()로 생성할 수 있으며, 종료될 때 세 가지 상태를 갖게된다.

  • Pending(대기): 이행하거나 거부되지 않은 초기 상태
  • Fulfilled(이행): 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(거부): 실패하거나 오류가 발생한 상태

Promise는 resolvereject 2개의 인자를 받으며, 비동기 처리가 성공하면 resolve가 호출되고, 실패하면 reject가 호출된다.


Promise Chaining

Promise의 특징 중 하나는 여러개의 Promise를 then()을 이용해서 연결하여 사용할 수 있다는 점이다.

function getData() {
  return new Promise({
    // ...
  });
}

// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
  .then(function(data) {
    // ...
  })
  .then(function() {
    // ...
  })
  .then(function() {
    // ...
  });

------------------------------------------

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

참조
velopert - Promise
Captain Pangyo - 자바스크립트 Promise 쉽게 이해하기
MJ KIM - 자바스크립트 비동기 함수 알아보기

profile
최근 공부 내용 정리 Notion Link : https://western-hub-b8a.notion.site/Study-5f096d07f23b4676a294b2a2c62151b7
post-custom-banner

0개의 댓글