개발자 9Diin의 개발일기

자바스크립트 Promise란 무엇인가? 본문

2021-2023

자바스크립트 Promise란 무엇인가?

9Diin 2022. 7. 22. 11:48
반응형

https://sungjaecloud.tistory.com/355

 

자바스크립트 콜백 함수란 무엇인가?

https://www.daleseo.com/js-async-callback/ [자바스크립트] 비동기 처리 1부 - Callback Engineering Blog by Dale Seo www.daleseo.com Callback함수란?? 뭔데?? 아 진짜 짜증났다...넌 힘내라!! 커몬~~ velog...

sungjaecloud.tistory.com

 

비동기 처리 Promise를 알아보기 전에 ES6에서 Promise가 도입되어 널리 사용되기 전의 문제점을 한 번 살펴보고 갈 필요가 있다고 생각한다. 콜백 함수를 통한 비동기 처리의 문제점은 무엇이 있을까?

 

findUserAndCallBack(1, function (user) {
  console.log("user:", user);
});

function findUserAndCallBack(id, cb) {
  setTimeout(function () {
    console.log("waited 0.1 sec.");
    const user = {
      id: id,
      name: "User" + id,
      email: id + "@test.com",
    };
    cb(user);
  }, 100);
}

// 결과
waited 0.1 sec.
user: {id: 1, name: "User1", email: "1@test.com"}

단순한 코드를 작성할 때는 위와 같이 전통적인 방식으로 콜백을 통해 비동기 처리를 해도 큰 문제가 없었다고 한다. 그런데 연쇄적으로 콜백을 호출해야 하는 경우에는 콜백 지옥이라 불리는 문제가 발생한다고 한다. 결국 이러한 문제점들을 해결하기 위해 탄생된 녀석이 Promise라고 이해하면 될 것 같다.


1️⃣ Promise의 개념

Promise는 현재 시점에는 당장 얻을 수 없지만, 가까운 미래에는 얻을 수 있는 어떤 데이터에 접근하기 위한 방법이다. 당장 원하는 데이터를 얻을 수 없다는 것은 데이터를 얻는 데까지 지연시간(delay, latency)이 발생하는 경우를 말한다. 자바스크립트에서는 필수라고 생각하면 된다. 공식문서를 한 번 살펴보자.

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise - JavaScript | MDN

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다고 한다. 기본적으로 Promise는 함수에 콜백을 전달하는 것이 아닌 콜백을 첨부하는 방식의 객체이다. 

 

예를 들어, 비동기로 음성 파일을 생성해주는 createAudioFileAsync라는 함수가 있었다고 생각해보자. 해당 함수는 음성 설정에 대한 정보를 받고, 두 가지 콜백 함수를 받는다. 하나는 음성 파일이 성공적으로 생성되었을 때 실행되는 콜백, 그리고 다른 하나는 에러가 발생했을 때 실행되는 콜백이다.

 

// 전통적인 코드 작성방법

function successCallback(result) {
  console.log("Audio file ready at URL: " + result);
}

function failureCallback(error) {
  console.log("Error generating audio file: " + error);
}

createAudioFileAsync(audioSettings, successCallback, failureCallback);

모던한 함수들은 위와 같이 콜백들을 전달하지 않고, 콜백을 붙여 사용할 수 있게 Promise를 반환해준다.

만약 createAudioFileAsync 함수가 Promise를 반환하도록 수정한다면, 아래와 같이 간단하게 사용될 수 있다.

 

createAudioFileAsync(audioSettings).then(successCallback, failureCallback);

좀 더 간단히 써보자면(?)

 

const promise = createAudioFileAsync(audioSettings);
promise.then(successCallback, failureCallback);

우리는 이와 같은 것을 비동기 함수 호출이라고 부른다. 이런 관례는 몇 가지 장점을 갖고 있다. 각각에 대해 한번 살펴보도록 하자.


😎 Guarantees

콜백 함수를 전달해주는 고전적인 방식과는 달리 Promise는 아래와 같은 특징을 보장한다.

 

첫째, 콜백은 자바스크립트 Event Loop가 현재 실행 중인 콜 스택을 완료하기 이전에는 절대 호출되지 않는다.

둘째, 비동기 작업이 성공하거나 실패한 뒤에 then 메서드를 이용하여 추가한 콜백의 경우에도 위와 같다. 셋째, then 메서드를 여러 번 사용하여 여러 개의 콜백을 추가할 수 있다. 그리고 각각의 콜백은 주어진 순서대로 하나하나 실행되게 된다.

 

Promise의 가장 뛰어난 장점 중 하나는 Chaining이다.


😎 Chaining

보통 두 개 이상의 비동기 작업을 순차적으로 실행해야 하는 상황을 흔히 보게 된다. 순차적으로 각각의 작업이 이전 단계 비동기 작업이 성공하고 나서 그 결괏값을 이용하여 다음 비동기 작업을 실행해야 하는 경우를 의미한다. 우리는 이런 상황에서 promise chain을 이용하여 해결하기도 한다.

 

then 메서드는 새로운 promise를 반환한다. 처음에 만들었던 promise와는 다른 새로운 promise이다.

 

const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
const promise2 = doSomething().then(successCallback, failureCallback);

두 번째 promise는 doSomething 뿐만 아니라 successCallback or failureCallback의 완료를 의미한다. successCallback or failureCallback 또한 promise를 반환하는 비동기 함수일 수도 있다. 이 경우 promise2에 추가된 콜백은 successCallback 또는 failureCallback에 의해 반환된 promise 뒤에 대기한다. 기본적으로, 각각의 promise는 체인 안에서 서로 다른 비동기 단계의 완료를 나타낸다.

 

예전에는 여러 비동기 작업을 연속적으로 수행하면 고전적인 '지옥의 콜백 피라미드'가 만들어졌었다.

 

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

모던한 방식으로 접근한다면, 우리는 콜백 함수들을 반환된 promise에 promise chain을 형성하도록 추가할 수 있다.

 

doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
반응형