jQuery 1.5 에서 deferred 대상 의 코드 사용(번역)

10812 단어 jQuerydeferred
역자 주:1. Deferred 는 jQuery 1.5 에 추 가 된 특성 으로 많은 사람들 이 이 를'비동기 대기 열'으로 번역 합 니 다.저 는 비교적 믿 을 만하 다 고 생각 합 니 다.왜냐하면'지연'과 아무런 관계 가 없 지만 이 글 에서 저 는 deferred 라 는 단 어 를 사용 합 니 다.
2. 이 글 은 jQuery 1.5 블 로그 에 올 라 왔 으 며,현재 deferred 가 비교적 전형 적 이 고 깊이 있 는 글 을 소개 하고 있다.현재 중국어 자료 가 비교적 적은 것 을 감안 하여 특별히 번역 하여 여러분 들 이 참고 하도록 제공 합 니 다.
3. 전편 은 의역 방식 을 채택 하 였 으 니,만약 부당 하 다 면 여러분 께 서 제기 해 주 십시오.
jQuery 1.5 에 추 가 된 Deferreds 대상 은 작업 이 완 료 된 처리 방식 을 작업 자체 와 결합 시 킬 수 있 습 니 다.이 는 자 바스 크 립 트 커 뮤 니 티 에서 새로운 것 이 없다.모 치 킷 과 Dojo 두 JS 프레임 워 크 가 이 특성 을 실현 한 지 오래 되 었 기 때문이다.그러나Julian AubourgjQuery 1.5 의 AJAX 모듈 을 재 작성 하면 서 deferreds 는 당연히 내부 의 실현 논리 가 되 었 다.deferreds 대상 을 사용 하면 여러 개의 리 셋 함 수 는 작업 이 완 료 될 때 실 행 될 수 있 고 심지어 작업 이 완 료 된 후에 이 리 셋 함 수 를 연결 할 수 있 습 니 다.이 임무 들 은 비동기 적일 수도 있 고 동기 화 될 수도 있다.
더 중요 한 것 은 deferreds 가$.ajax()의 내부 로 구현 되 었 기 때문에 AJAX 를 호출 할 때 deferreds 가 가 져 온 것 을 자동 으로 가 져 올 수 있 습 니 다.예 를 들 어 우 리 는 이렇게 리 셋 함 수 를 연결 할 수 있다.
 
// $.get, AJAX
var req = $.get('foo.htm').success(function (response) {
// AJAX
}).error(function () {
// AJAX
});
// AJAX
doSomethingAwesome();
// AJAX , AJAX ,
// $.ajax deferred ,
req.success(function (response) {
// AJAX , AJAX
});
우 리 는 더 이상 하나의 성공,실패 또는 완 성 된 리 셋 함수 로 제한 되 지 않 는 다.반대로 수시로 추 가 된 리 셋 함 수 는 선진 적 인 선 출 대기 열 에 놓 여 있다.위의 예 에서 보 듯 이 리 셋 함 수 는 AJAX 요청(관찰 가능 한 작업 observable task)에 추가 되 고 심지어 AJAX 요청 이 끝 났 습 니 다.코드 의 조직 은 매우 좋 으 므 로 우 리 는 더 이상 긴 반전 함 수 를 쓸 필요 가 없다.이것 은$.queue()가 pub/sub(게시 구독 체제,일반적으로 이벤트 처리 모델 에 사 용 됩 니 다)를 만난 것 과 같 습 니 다.좀 더 깊이 있 게,이러한 장면 을 상상 하고,동시에 발생 하 는 AJAX 요청 이 모두 끝 난 후에 리 셋 함 수 를 실행 합 니 다.jQuery 함수$.when()을 통 해 편리 하 게 완성 할 수 있 습 니 다.
 
function doAjax() {
return $.get('foo.htm');
}

function doMoreAjax() {
return $.get('bar.htm');
}

$.when(doAjax(), doMoreAjax()).then(function () {
console.log('I fire once BOTH ajax requests have completed!');
}).fail(function () {
console.log('I fire if one or more requests failed.');
});
jsFiddle 에서 예제 열기
위의 예제 가 정상적으로 실 행 될 수 있 습 니 다.이것 은 모든 jQuery 의 AJAX 방법 반환 값 에 promise 함 수 를 포함 하여 비동기 요청 을 추적 하 는 데 사 용 됩 니 다.Promise 함수 의 반환 값 은 deferred 대상 의 읽 기 전용 보기 입 니 다.(The promise is a read-only view into the result of the task.)Deferreds 는 검사 대상 에 promise()함수 가 존재 하 는 지 여 부 를 통 해 현재 대상 이 관찰 할 수 있 는 지 여 부 를 판단 합 니 다.$.when()은 모든 AJAX 요청 이 끝 날 때 까지 기 다 렸 다가.then(),.fail()을 통 해 등 록 된 리 셋 함수(어떤 리 셋 함 수 를 구체 적 으로 호출 하 느 냐 는 작업 의 종료 상태 에 달 려 있 습 니 다)를 호출 합 니 다.이 반전 함 수 는 그들의 등록 순서에 따라 실 행 될 것 이다.
더 좋 은 것 은$.when()이 함수 나 함 수 를 받 아들 이 는 배열 을 매개 변수 로 하 는 것 입 니 다.함수 배열 을 매개 변수 로 할 수 없 음 을 주의 하 십시오).그러면 비동기 작업 을 마음대로 조합 할 수 있 습 니 다.
$.ajax()는 대상 을 되 돌려 줍 니 다.이 대상 은 promise(),then(),success(),error()와 연 결 된 deferred 함수 입 니 다.그러나 원본 deferred 대상 을 조작 할 수 없습니다.promise()함수 만 있 습 니 다.
그런데 왜 deferred 대상 으로 돌아 가지 않 습 니까?만약 에 완전한 deferred 대상 을 되 돌려 준다 면 우 리 는 더 많은 통 제 를 가지 게 될 것 입 니 다.아마도 마음대로 트리거 할 수 있 을 것 입 니 다.따라서 원 하지 않 는 deferred 의 위험 을 피하 기 위해 서 는 dfd.promise()만 되 돌려 야 합 니 다.(그러므로 potentially breaking the whole paradigm,only return the dfd.promise().)나 는 그 중의 원인 등록 리 셋 함수(Registering Callbacks)위의 예 에서 우 리 는 then(),success(),fail()방법 으로 리 셋 함 수 를 등록 할 것 이다.사실은 더 많은 방법 을 사용 할 수 있다.특히 AJAX 요청 을 처리 할 때.구체 적 으로 어떤 방식 을 사용 하 느 냐 는 결과 상태 에 대한 관심 에 달 려 있다.모든 deferred 대상 에 있 는 함수(AJAX,$.when 또는 수 동 으로 만 든 deferred 대상):
 
.then( doneCallbacks, failedCallbacks )
.done( doneCallbacks )
.fail( failCallbacks )
AJAX 대상 에는 3 개의 추가 방법 이 포함 되 어 있 으 며,그 중 두 개 는 위 에서 언급 한 방법 에 반영 된다.이 방법 들 은 주로 이전의 코드 를 호 환 하기 위해 서 입 니 다.
 
// "success" "error" "done" and "fail"
.success( doneCallbacks )
.error( failCallbacks )
당신 도 complete 의 리 셋 함 수 를 등록 할 수 있 습 니 다.이 요청 이 성공 하 든 실패 하 든 간 에 요청 이 끝 난 후에 호출 될 것 입 니 다.success 나 error 함수 와 달리 complete 함 수 는 단독 deferred 대상 의 done 함수 별명 입 니 다.$.ajax()내부 에 만 든 deferred 대상 은 AJAX 가 끝 난 후에 리 셋 함수(resolve)를 촉발 합 니 다.
 
.complete( completeCallbacks )
따라서 다음 세 가지 예 는 등가 입 니 다.(AJAX 의 문맥 에서 success 는 done 함수 보다 편 해 보 입 니 다.맞 습 니까?)(번역자 주:사실은 우리 가 예전 의 AJAX 호출 방식 을 잘 알 고 있 기 때 문 입 니 다.선입견 을 가지 거나 사고방식 의 정 세 를 가지 고 있 기 때 문 입 니 다.
 
$.get("/foo/").done( fn );
// :
$.get("/foo/").success( fn );
// :
$.get("/foo/", fn );
자신의 deferred 대상(Creating your own Deferred)을 만 들 었 습 니 다.우 리 는$.ajax 와$.when 이 내부 에서 deferred 인 터 페 이 스 를 실현 한 것 을 알 고 있 습 니 다.그렇지 않 아 도 우 리 는 수 동 으로 deferred 대상 을 만 들 수 있 습 니 다.
 
function getData() {
return $.get('/foo/');
}
function showDiv() {
var dfd = $.Deferred();
$('#foo').fadeIn(1000, dfd.resolve);
return dfd.promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('The animation AND the AJAX request are both done!');
// 'ajaxResult' ( : getData AJAX )
});
jsFiddle 에서 예제 열기쇼 Div()에서우 리 는 deferred 대상 을 만 들 고 애니메이션 을 실행 한 후에 promise 로 돌 아 왔 다.이 deferred 대상 은 fadein()이 끝 난 후에 트리거 됩 니 다(resolved).이 promise 반환 과 deferred 대상(주의:여기 deferred 는$.when 이 만 든 대상 을 말 합 니 다.showDiv()가 돌아 오 는 대상 이 아 닌)이 촉발 하 는 중간 에 then()반전 함수 가 등 록 됩 니 다.이 반전 함 수 는 두 개의 비동기 작업 이 모두 끝 난 후에 실 행 될 것 이다.getData()는 대상 을 되 돌려 줍 니 다.The manually steps we took to return a promise in showDiv()is handled for us internally by$.ajax()and$.when().1/15/2011:Julian 은 댓 글 에서 위의 문법 을$.Deferred(fn).promise()로 간소화 할 수 있다 고 지적 했다.따라서 아래 의 양쪽 코드 는 등가 입 니 다.
 
function showDiv() {
var dfd = $.Deferred();
$('#foo').fadeIn(1000, dfd.resolve);
return dfd.promise();
}
// :
function showDiv() {
return $.Deferred(function (dfd) {
$('#foo').fadeIn(1000, dfd.resolve);
}).promise();
}
사용자 정의 deferred 대상 에 리 셋 함수(Defer your Deferreds)를 추가 하면 getData()와 showDiv()에 리 셋 함 수 를 각각 등록 할 수 있 습 니 다.마치 우리 가$.then()에 리 셋 함 수 를 등록 한 것 과 같 습 니 다.(번역자 주:아래 단락 의 내용 이 중복 되 고 말 하 는 것 은 모두 한 뜻 이 므 로 번역 하지 않 겠 습 니 다.코드 를 보 세 요.
 
function getData() {
return $.get('/foo/').success(function () {
console.log('Fires after the AJAX request succeeds');
});
}
function showDiv() {
return $.Deferred(function (dfd) {
// : , jsFiddle 。
// , deferred
dfd.done(function () {
console.log('Fires after the animation succeeds');
});
$('#foo').fadeIn(1000, dfd.resolve);
}).promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('Fires after BOTH showDiv() AND the AJAX request succeed!');
// 'ajaxResult'
});
jsFiddle 에서 예제 열기체인 코드(Chaining Hotness)Deferred 의 리 턴 함 수 는 체인 으로 호출 할 수 있 습 니 다.함수 가 deferred 대상 으로 되 돌아 오 면(번역자 주:dfd.promise()는 읽 기 전용 deferred 대상 으로 되 돌아 갑 니 다.이것 은 실제 코드(via@ajpiano!)
 
function saveContact(row) {
var form = $.tmpl(templates["contact-form"]),
valid = true,
messages = [],
dfd = $.Deferred();
/*
*
*/
if (!valid) {
dfd.resolve({
success: false,
errors: messages
});
} else {
form.ajaxSubmit({
dataType: "json",
success: dfd.resolve,
error: dfd.reject
});
}
return dfd.promise();
};
saveContact(row).then(function (response) {
if (response.success) {
// ,
} else {
//
//
}
}).fail(function (err) {
// AJAX
});
saveContact()함 수 는 먼저 폼 데이터 의 유효성 을 검증 한 다음 에 유효성 상 태 를 변수 valid 에 저장 합 니 다.인증 에 실패 하면 직접 deferred 가 실 행 됩 니 다.(success 상태 코드 와 오류 정 보 를 포함 하 는 JS 대상 을 매개 변수 로 리 셋 함수 에 전달 합 니 다.)검증 이 통과 되면 서버 에 데 이 터 를 제출 하고 AJAX 가 성공 적 으로 완료 되면 deferred 대상 을 터치 합 니 다.fail()은 404,500 등 AJAX 요청 이 성공 적 으로 완료 되 는 것 을 막 을 수 있 는 HTTP 상태 코드 를 처리 합 니 다.관찰 할 수 없 는 작업(Non-observable Tasks)Deferreds 는 비동기 작업 이나 동기 화 작업 이 아 닌 디 결합 작업 과 작업 처리 함수 에 유용 합 니 다.하나의 작업 은 promise 로 돌아 갈 수도 있 지만 문자열,대상 또는 다른 형식 으로 돌아 갈 수도 있 습 니 다.이 예 에서'Lanch Application'링크 가 처음 클릭 되 었 을 때 AJAX 요청 이 서버 에 전송 되 고 현재 시간 표를 되 돌려 줍 니 다.그리고 이 시간 스탬프 는 이 링크 의 data 캐 시 에 저 장 됩 니 다.이 링크 가 다시 클릭 되 었 을 때,AJAX 요청 대신 캐 시 에서 이 시간 표를 간단하게 꺼 내 되 돌려 줍 니 다.
 
function startTask(element) {
var timestamp = $.data(element, 'timestamp');
if (timestamp) {
return timestamp;
} else {
return $.get('/start-task/').success(function (timestamp) {
$.data(element, 'timestamp', timestamp);
});
}
}
$('#launchApplication').bind('click', function (event) {
event.preventDefault();
$.when(startTask(this)).done(function (timestamp) {
$('#status').html('<p>You first started this task on: ' + timestamp + '</p>');
});
loadApplication();
});
$.when()이 첫 번 째 매개 변수 에 promise 함수 가 없 음 을 발견 하면 새로운 deferred 대상 을 만 들 고 deferred 대상 을 촉발 하 며 promise 읽 기 대상 만 되 돌려 줍 니 다.따라서 관찰 할 수 없 는 임 무 를$.when()에 전달 할 수 있 습 니 다.주의해 야 할 문 제 는 대상 자체 가 promise 함 수 를 가지 고 있다 면 이 대상 은 deferred 대상 이 될 수 없다 는 것 이다.jQuery 는 대상 이 deferred 인지 여 부 를 판단 합 니 다.promise 함수 가 있 는 지 확인 하여 결정 합 니 다.그러나 jQuery 는 이 promise 가 정말 사용 가능 한 대상 으로 돌아 가 는 지 확인 하지 않 습 니 다.따라서 다음 코드 는 오류 가 발생 할 수 있 습 니 다.
 
var obj = {
promise: function () {
// do something
}
};
$.when(obj).then(fn);
결론(Conclusion)Deferreds 는 새로운 건장 한 방식 으로 비동기 임 무 를 처리 하 는 것 을 제 시 했 습 니 다.전통 적 으로 코드 를 하나의 리 셋 함수 에 구성 하 는 것 과 달리 새로운 deferred 대상 은 우리 가 언제든지(심지어 작업 이 끝 난 후에)여러 개의 리 셋 함 수 를 연결 할 수 있 도록 합 니 다.이러한 리 셋 함 수 는 선진 적 으로 먼저 나 오 는 방식 으로 호출 됩 니 다.이 글 의 정 보 는 소화 하기 어 려 울 수 있 지만,deferred 대상 의 사용 을 파악 하면 비동기 적 으로 실행 되 는 코드 를 조직 하 는 것 이 매우 쉬 울 것 이다.이 글 은 삼생 석 에서 오리지널 로 제작 되 었 으 며,블 로그 원 에서 최초 로 게재 되 었 으 니,전재 할 때 출처 를 밝 혀 주 십시오.

좋은 웹페이지 즐겨찾기