Language/JavaScript

Promise와 jQuery Deferred Object

SambaLim 2020. 7. 24. 23:07

Promise, jQuery Deferred Object

JS에서 비동기 처리를 할경우, 콜백함수를 사용하곤 합니다.

하지만, 이러한 콜백함수를 사용하는 것은 복잡도를 높입니다. 이를 해결하기 위한 Promise와 jQuery Deferred Object를 알아보도록 합시다.

예시 - 콜백함수

const callback = function() {
    console.log('Callback!');
}

const hellStart = function(one) {
    setTimeout(function() {
        one();
    }, 3000);
}

hellStart(callback);

콜백함수를 사용하여 비동기를 처리할경우, 여러 개의 콜백함수가 nesting되어 복잡도가 높아질 수 있습니다.

이를 콜백지옥이라하는데, 콜백지옥은 코드의 가독성을 떨어뜨릴뿐만아니라 에러처리가 어렵습니다.

예시 - 에러처리

const throwError = function() {
    throw 'Throw Error!';
}

try {
    setTimeout(throwError, 3000);
} catch(error) {
    console.log(error); // Uncaught Throw Error!
}

위의 예시의 경우 에러가 Uncaught 됩니다.

이러한 콜백함수의 문제점을 해결하기 위해서 Promise가 고안되었다. 마찬가지로 jQuery에서는 Deferred Object가 고안되었습니다.

우선 Promise와 jQuery Deferred Object에 대해 알아보도록 합시다.

Promise

Promise를 사용하기 위해서는 status(상태)를 이해하고 있어야 합니다.

status(상태)는 new Promise() 로 프로미스를 생성하고 종료할때까지 3가지 상태를 갖습니다.

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

Pending(대기)

new 연산자를 통해 Promise를 생성하면 Pending(대기) 상태가 됩니다.

new Promise() 메서드를 호출할 때 콜백함수를 선언할 수 있고 인자는 resolve , reject 입니다.

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

Fulfilled(이행)

콜백함수의 인자 resolve 를 실행하게 되면 Fulfilled(이행) 상태가 됩니다.

'예시-콜백함수' 코드를 Promise를 적용하면 다음과 같이 바뀝니다.

(* 예시를 위해 data 를 추가하였습니다.)

예시 - Promise

const callback = function() {
    console.log('Callback!');
}

const hellStart = function(one) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            let data = 300;
            resolve(data);
        }, 3000);
    });
}

hellStart().then(function(resolvedData) {
    console.log(resolvedData);
    callback();
});

Fulfilled(이행) 상태가 되면 위의 예시와 같이 then()을 통해 처리 결과값을 받을 수 있습니다.

Rejected(실패)

reject를 호출하여 프로미스를 Rejected(실패) 상태로 만들고 실패처리 결과 값을 catch() 로 받을 수 있습니다.

const getError = function() {
    return new Promise(function(resolve, reject) {
        reject(new Error("Error is occured!"));
    });
}

getError().then().catch(function(error) {
    console.log(error);
});

Promise는 이와같이 3개의 상태값을 가지고 동작합니다.

3개의 상태값을 기억하고 사용할 수 있다면 기존 콜백지옥에서 벗어나실 수 있을겁니다. 이제 콜백지옥을 벗어날 또 한가지 방법으로 jQuery Deferred Object를 보고자 합니다.

jQuery Deferred Object

jQuery Deferred Object는 Promise를 구현한 jQuery 객체입니다. Promise를 사용할 수 없는 환경에서 주로 사용합니다.

jQuery Deferred Object도 Promise와 같이 상태값을 3가지 가지고 있습니다. 상태의 변화는 deferred.state() 를 통해 확인하실 수 있습니다.d

  • Pending(대기)
  • Resolved(처리 성공)
  • Rejected(처리 실패)

Pending(대기)

$.Deferred() 로 Deferred 객체를 생성하면 Pending(대기) 상태가 됩니다.

resolve() 또는 reject() 로 State를 변화시킬 수 있습니다.

var deferred = $.Deferred();

Resolved(처리 성공)

Pending 상태인 Deferred객체에서 resolve() 메소드를 실행하게되면 Resolved(처리 성공)상태가 됩니다.

예시 - Deferred Object Resolved

var hellStart = function(one) {
  var deferred = $.Deferred();

  setTimeout(function() {
    var data = 300;
    deferred.resolve(data);
  }, 3000);

  return deferred.promise();
}

hellStart().done(function(data) {
  console.log(data);
});

Resolved 상태가 되었을 경우, 위의 예시와 같이 인자를 넘길수도 있습니다.

Rejected(처리 실패)

Pending 상태인 Deferred객체에서 reject() 메소드를 실행하게 되면 Rejected(처리 실패) 상태가 되고 실패처리 결과 값을 fail() 을 통해 받을 수 있습니다.

var hellStart = function(one) {
  var deferred = $.Deferred();

  setTimeout(function() {
    deferred.reject(new Error('Error is occured'));
  }, 3000);

  return deferred.promise();
}

hellStart().done().fail(function(error) {
  console.log(error);
});

마무리

Promise와 jQuery Deferred Object의 각 상태를 알아보고 이에대한 예시를 보았습니다.

가독성과 에러처리를 위해 콜백지옥을 계속만들기보다 jQuery를 사용해야 하는 경우에는 jQuery Deferred Object를 사용해야겠습니다.

참고자료