Javascript 의 Promise 와 Deferred 에 대해 잊기 전에 살짝 메모해 봅니다.
아래 내용은 개인적으로 이러한 스펙이 있다는 것을 인지하기 위해 적어두는 내용으로 추후에 필요에 의해 사용 시 저 역시 상세한 내용은 검색을 통해 사용 할 생각으로 간단히 메모해 보고자 합니다.
그리고 아래 내용은 http://blog.naver.com/sef16 님의 Promise, Deferred 관련 글에서 많은 참고를 하였습니다.
- Promise
jQuery 1.5 이후 부터 $.ajax, $.get, $.post 에 Promise 가 사용 가능해졌다고 합니다.
먼저 예제부터 보면
$.get('url', {
success: callbackSuccess
, failure: callbackFailure
, always: callbackAlways
});
는 아래와 같이 변경이 가능합니다.
var promise = $.get('url');
promise.done(callbackSuccess); // sucecss
promise.fail(callbackFailure); // failed
promise.always(callbackAlways); // always (ajax complete)
이는 공통적인 코드의 중복 제거 해결에 매우 요긴하게 사용이 될 것으로 보입니다.
이를테면 화면 로딩바의 컨트롤이나
async_func(first, function() {
async_func(second, function() {
async_func(third, function() {
});
})
});
와 같은 콜백지옥에서 자유로워 질 수 있으리라 생각되네요.
- Deferred
$.Deferred 는 Promise 가 해당 Promise 객체에 콜백을 등록만 할 수 있는 것에 반해
Deferred 의 콜백 함수를 직접 트리거 할 수 있습니다.
var deferred = new $.Deferred();
deferred.done(function() { console.log('def done'); });
deferred.fail(function() { console.log('def fail'); });
deferred.always(function() { console.log('def always'); }); // jQuery 1.6 이상에서만 가능
$('#btn_done').on('click', function() {
deferred.resolve(); // console :: def done def always
});
$('#btn_fail').on('click', function() {
deferred.reject(); // console :: def fail def always
});
여기서 한 가지 주의해야 할 것은 콜백 함수는 순서 대로 바인드 된다는 것입니다.
만약
deferred.always(function() { console.log('def always'); }); // jQuery 1.6 이상에서만 가능
deferred.done(function() { console.log('def done'); });
deferred.fail(function() { console.log('def fail'); });
순으로 하였다면 콘솔은 def always def done, def always def fail 순으로 찍히게 됩니다.
또한 Deferred 에서 Promise 를 만들 수 있습니다.
var _promise = deferred.promise();
를 하게 되면 Promise 객체가 리턴이 됩니다.
여기서도 주의해야 할 것은 내부적으로 같은 콜백을 공유하기 때문에 콜백함수를 deferred 에 정의하든 _promise 에 정의하든 같다는 것입니다.
그리고 Promise 는 아래와 같은 3가지의 상태값을 가진다고 합니다. (Mozilla Deleoper Network)
대기중(pending): 초기 상태, 이행 또는 거부되지 않은.
이행됨(fulfilled): 연산이 성공리에 완료되었음을 뜻합니다.
거부됨(rejected): 연산이 실패했음을 뜻합니다.
처리됨(settled) : 대기중이 아니라 이행 또는 거부된 경우
현재는 이렇게 확인이 가능하다고 하는 데 예전 글들을 살펴보니 jQuery 1.7 이후에 이렇게 가능해 진 것이고
그 이전에는 isResolve, isReject 가 사용되었다고 합니다.
** 이 외에도 특정 context 안에 있는 콜백을 호출 할 수도 있고 (resolveWith 와 rejectWith 사용)
1개 이상의 Promise 들을 합쳐서 모두 끝났을 때 실행 할 수도 있는 (when 사용) 등 많은 내용이 있습니다.