이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌13 - jQuery - 2년 전 등록

제이쿼리 프로미스(promise)와 Deferred

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 제이쿼리의 프로미스 기능과 deferred 객체에 대해 알아보겠습니다. 지난 AJAX 시간에도 살짝 다뤘는데요. 프로미스를 사용하면 비동기 프로그래밍을 할 때 코드를 간결하게 관리할 수 있습니다.

제이쿼리 프로미스는 기본적으로 공식 구현을 따르지 않아서 문제가 있습니다. 에러 처리와 프로미스 실행 순서에 관한 문제입니다. 하지만 복잡한 프로미스를 구현하지 않는 이상은 그 문제가 발생하지 않기 때문에 그냥 사용하셔도 됩니다. (제이쿼리 3.0에서는 그 문제가 해결되었습니다)

제이쿼리는 프로미스를 사용할 수 있게 Deferred라는 객체를 제공합니다. 이 객체를 사용하면 일반 코드도 프로미스처럼 사용할 수 있습니다.

일단 제이쿼리 프로미스의 기본 구조는 프로미스 객체가 완료되었을 때 done 메소드가 호출되고 실패했을 때는 fail, 완료되었건 실패했건 행동이 끝났으면 always가 호출됩니다. 아주 오래 걸리고 복잡한 함수가 다음과 같이 있다고 가정해봅시다.

var longAndComplicatedFunction = function() {
  try {
    // 완료되려면 50초가 걸리는 매우 복잡한 코드
    console.log('성공');
  } catch (err) {
    console.log('실패');
  }
};
longAndComplicatedFunction();
console.log('다음 행동');

이렇게 복잡한 코드가 있으면 이 코드를 실행하는 50초 동안은 아무 것도 할 수 없습니다. 50초 후에야 다음 행동이 실행될 겁니다. 사용자들은 멍하니 기다리거나 화가 나서 앱을 종료할 겁니다.

$.Deferred

이렇 때 비동기 프로그래밍이 필요합니다. 흔히 콜백 형식이나 프로미스 형식을 사용하는 데, 콜백 형식은 점점 더 코드가 복잡해지는 문제를 발생시키기 때문에, 콜백이 여러 번 중첩될 것 같으면 프로미스 형식을 사용해야합니다. 다음과 같이 위의 코드를 바꿔봅시다.

var longAndComplicatedFunction = function() {
  var deferred = $.Deferred();
  try {
    // 완료되려면 50초가 걸리는 매우 복잡한 비동기 코드
    deferred.resolve('성공');
  } catch (err) {
    deferred.reject(err);
  }
  return deferred.promise();
};
longAndComplicatedFunction().done(function(message) {
  console.log(message);
}).fail(function(error) {
  console.log(error);
}).always(function() {
  console.log('완료!');
});
console.log('다음 행동');

이렇게 $.Deferred()로 deferred 객체를 만들고, 성공했을 때에는 resolve, 실패했을 때에는 reject 메소드를 호출하면 resolve는 done으로, reject는 fail로 연결됩니다.

이제 비동기 방식으로 했기 때문에 다음 행동은 50초를 기다릴 필요 없이 바로 실행되고, 복잡한 행동이 완료되었을 시 등록해둔 done 메소드가 실행됩니다. 실패했다면 fail 메소드가 실행되고요. longAndComplicatedFunction 함수에서 deferred.promise()를 return하는 것을 잊지 마세요!

참고로 done이나 fail로 구분하지 않고 한 번에 처리하려면 then 메소드가 있습니다. 첫 번째 인자는 성공 시 콜백이고, 두 번째 인자는 실패 시 콜백입니다. then도 연달아 쓸 수 있습니다.

longAndComplicatedFunction().then(function(message) {
  console.log(message);
}, function(error) {
  console.log(error);
}).then(function() {
  console.log('완료!');
});

여기까지는 흔한 제이쿼리 프로미스 방식이고 ES2015의 프로미스와도 상당히 유사합니다. 제이쿼리의 장점은 추가 메소드를 제공하는 겁니다.

$.when

$.when은 여러 개의 비동기 프로미스 함수를 동시에 처리할 수 있게 해줍니다.

$.when(longAndComplicatedFunction(), longerAndMoreComplicatedFunction()).done(function(result1, result2) {
  console.log(result1, result2);
});

$.when 안에 여러 개의 프로미스 함수를 넣어줍니다. 함수들이 모두 종료되었을 때 연결해둔 done 메소드의 콜백이 실행됩니다. longAndComplicatedFunction의 결과는 result1으로, longerAndMoreComplicatedFunction의 결과는 result2로 연결됩니다.

여러 개의 프로미스를 동시에 처리할 수 있기 때문에 편리합니다. 특히 선행 조건으로 비동기 함수 여러개가 필요한 경우 $.when을 쓰면 효과적으로 코딩을 할 수 있습니다. done 메소드에서 비동기 함수의 결과들을 한 번에 받을 수 있으니까요.

이상으로 제이쿼리 강좌를 마치겠습니다. 혹시나 제이쿼리에 변경 사항이나 추가 사항이 있다면 그 때 포스팅하겠습니다!

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

2개의 댓글이 있습니다.
7달 전
업무에 큰 도움이 되었습니다. 감사합니다. ^^
2년 전
하루동안 재미있게 잘봤습니다 ㅎㅎ 감사합니다!
2년 전
감사합니다~