번역자 주:
1. Deferred는 jQuery1.5의 새로운 기능입니다. ", 결국 "지연"과는 아무런 관련이 없지만 이 기사에서는 여전히 연기라는 단어를 사용하는 것이 더 신뢰할 수 있다고 생각합니다.
2. 이 글은 jQuery1.5 릴리즈 블로그에 언급된 글이며, Deferred를 소개하는 가장 고전적이고 심도 있는 글이기도 합니다. 현재 중국어 자료가 상대적으로 적다는 점을 고려하여 모든 사람의 학습과 참고를 위해 특별히 번역되었습니다.
3. 전체 기사는 무료 번역을 채택하고 있으며, 부적절한 내용이 있으면 지적해 주시기 바랍니다.
jQuery1.5에 새로 추가된 Deferreds 객체는 작업 완료 처리 방법을 작업 자체와 분리할 수 있습니다. 두 JS 프레임워크인 Mochikit과 Dojo가 오랫동안 이 기능을 구현해 왔기 때문에 이는 JavaScript 커뮤니티에서 새로운 것이 아닙니다. 그러나 Julian Aubourg가 jQuery 1.5에서 AJAX 모듈을 다시 작성하면서 지연은 자연스럽게 내부 구현 논리가 되었습니다. 지연된 개체를 사용하면 작업이 완료될 때 또는 작업이 완료된 후에도 여러 콜백 함수가 실행되도록 바인딩할 수 있습니다. 이러한 작업은 비동기식이거나 동기식일 수 있습니다.
더 중요한 것은 deferred가 $.ajax()의 내부 구현으로 구현되었으므로 AJAX를 호출할 때 deferred가 가져오는 순회를 자동으로 가져올 수 있다는 것입니다. 예를 들어 다음과 같이 콜백 함수를 바인딩할 수 있습니다. 위 예제는 각 jQuery AJAX 메서드의 반환 값에 비동기 요청을 추적하는 promise 함수가 포함되어 있다는 사실 덕분에 제대로 작동합니다. Promise 함수의 반환 값은 지연된 객체의 읽기 전용 보기입니다. (Promise는 작업 결과에 대한 읽기 전용 보기입니다.) Deferred는 promise() 함수가 객체에 존재하는지 감지하여 현재 객체를 관찰할 수 있는지 여부를 결정합니다. $.when()은 모든 AJAX 요청이 끝날 때까지 기다린 다음 .then(), .fail()을 통해 등록된 콜백 함수를 호출합니다(호출되는 특정 콜백 함수는 작업의 종료 상태에 따라 다릅니다). 이러한 콜백 함수는 등록된 순서대로 실행됩니다. 더 좋은 점은 $.when()이 함수 또는 함수 배열을 매개변수로 허용한다는 것입니다(번역자 참고 사항: $.when은 하나 이상의 지연된 객체 또는 기본 JS 객체를 허용합니다. 참고 함수 배열은 매개변수로 사용할 수 없음) 따라서 이러한 비동기 작업을 마음대로 결합할 수 있습니다. $.ajax()는 promise(), then(), Success(), error() . 그러나 원본 지연된 객체는 작동할 수 없으며 promise() 함수(역자 참고: 방금 언급한 promise는 읽기 전용 보기임을 기억하세요)와 지연된 상태를 감지할 수 있는 isRejected() 및 isResolved() 함수만 작동할 수 있습니다.
하지만 지연된 객체를 반환하는 것은 어떨까요? 완전한 지연된 객체가 반환되면 우리는 더 많은 제어권을 갖고 지연된 객체를 마음대로 트리거할 수 있습니다. (역자 주: 해결을 트리거로 번역했습니다. 이는 지연된 객체에 등록된 모든 콜백 함수를 트리거하는 것입니다.) 따라서 AJAX 요청이 끝나기 전에 모든 콜백 함수가 실행됩니다. 따라서 잠재적으로 전체 패러다임이 깨지는 것을 방지하려면 dfd.promise().promise()만 반환하세요. 위 문단은 상관없으니 나중에 자세히 이유를 분석하는 글을 쓰겠습니다콜백 함수 등록(Registering Callbacks) 위 예에서는 then(), Success(), failure를 사용했습니다. () 메서드를 사용하면 특히 AJAX 요청을 처리할 때 사용할 수 있는 메서드가 더 많습니다. 모든 지연된 개체에 사용할 수 있는 함수(AJAX, $) .언제 또는 수동으로 지연된 객체를 생성했는지): 이 작업을 처음 시작한 날짜: ' 타임스탬프 '
// $ .get, 비동기 AJAX 요청
var req = $.get('foo.htm').success(function (response) {
// 성공 후 AJAX 처리 함수
}).error( function () {
// AJAX 실패 후처리 함수
})
// 이 함수는 AJAX가 끝나기 전에
doSomethingAwesome()을 호출할 수 있습니다. 다른 AJAX 콜백 함수를 추가하세요. AJAX가 지금 종료되었거나 아직 종료되지 않았을 수 있습니다
// $.ajax에는 지연 지원이 내장되어 있으므로 다음과 같이 작성할 수 있습니다
req.success(function (응답) {
/ / 이 함수는 AJAX가 완료된 후 호출되거나 AJAX가 완료된 경우 즉시 호출됩니다.
})
위의 예에서 볼 수 있듯이 콜백 함수는 AJAX 요청이 종료된 후에도 AJAX 요청(관찰 가능한 모든 작업)에 첨부될 수 있습니다. 코드 구성은 매우 훌륭하여 더 이상 긴 콜백 함수를 작성할 필요가 없습니다. 이는 $.queue()가 pub/sub(이벤트 기반 모델에서 일반적으로 사용되는 게시-구독 메커니즘)를 충족하는 것과 같습니다.
좀 더 자세히 살펴보면 일부 동시 AJAX 요청이 모두 종료된 후 이와 같은 시나리오를 상상해 보세요. . jQuery의 $.when() 함수를 통해 쉽게 이 작업을 수행할 수 있습니다.
return $.get('foo.htm')
}
function doMoreAjax() {
return $.get('bar .htm');
}
$.when(doAjax(), doMoreAjax()).then(function () {
console.log('두 Ajax 요청이 모두 완료되면 실행됩니다. !');
}).fail(function () {
console.log('하나 이상의 요청이 실패하면 실행됩니다.');
jsFiddle에서 예제 열기
AJAX 개체에는 3개의 추가 메서드가 포함되어 있으며 그 중 2개는 언급된 메서드에 매핑됩니다. 위의 방법은 주로 이전 코드와의 호환성을 위한 것입니다.
요청의 성공, 실패 여부에 관계없이 요청이 완료된 후 호출되는 완전한 콜백 함수를 등록할 수도 있으며, 완료 함수는 실제로 별도의 완료 함수 별칭입니다. $.ajax() 내부에 생성된 이 지연 객체는 AJAX 종료 후 콜백 함수(resolve)를 트리거합니다.
코드 복사
코드 복사
자신만의 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('애니메이션과 AJAX 요청이 모두 완료되었습니다!' ; >다음을 엽니다. example in jsFiddle
showDiv()에서는 지연된 객체를 생성하고 애니메이션을 수행한 다음 Promise를 반환합니다. 이 지연된 객체는 fadeIn()이 끝난 후에 트리거(해결)됩니다. 이 Promise의 반환과 지연된 객체의 트리거 사이(참고: 여기서 지연된 객체는 showDiv()에 의해 반환된 객체가 아니라 $.when에 의해 생성된 객체를 나타냄) then() 콜백 함수가 등록됩니다. 이 콜백 함수는 두 비동기 작업이 모두 완료된 후에 실행됩니다. getData()는 $.when()이 이 AJAX 요청의 끝을 모니터링할 수 있도록 하는 promise 메서드를 사용하여 객체(번역자 참고: 실제로는 jQuery로 캡슐화된 XMLHttpRequest 객체)를 반환합니다. showDiv()에서 Promise를 반환하기 위해 수행한 수동 단계는 $.ajax() 및 $.when()에 의해 내부적으로 처리됩니다. 2011년 1월 15일: Julian은 주석에서 위 구문을 지적했습니다. $.Deferred(fn).promise()로 축소되었습니다. 따라서 양쪽 끝의 다음 코드는 동일합니다. 코드 복사
코드는 다음과 같습니다.
$('#foo').fadeIn(1000, dfd. 해결);
}).promise();
}
사용자 정의 지연 객체에 대한 콜백 함수 추가(지연 객체 연기)
한 단계 더 나아가 getData를 제공할 수 있습니다. () 및 showDiv()는 $.then()에 콜백 함수를 등록하는 것처럼 콜백 함수를 별도로 등록합니다. (번역자 주: 다음 문단은 중복되고 같은 의미이므로 번역하지 않겠습니다. 코드를 살펴보겠습니다)
코드 복사
코드는 다음과 같습니다:
dfd.done( function () {
console.log('애니메이션 성공 후 실행')
$('#foo').fadeIn(1000, dfd.resolve); ).promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('showDiv() 및 AJAX 모두 실행 후 실행 요청 성공!'); // 'ajaxResult'는 서버에서 반환된 결과입니다.
})
jsFiddle에서 예제를 엽니다.
Chaining Hotness
Deferred의 콜백 함수는 해당 함수가 지연된 객체를 반환하는 한 체인에서 호출할 수 있습니다(번역자 주: dfd.promise( )는 읽기 전용 지연 객체를 반환합니다. ). 실제 코드입니다(@ajpiano를 통해!)
코드 복사 코드는 다음과 같습니다.
function saveContact(row) {
var form = $.tmpl(templates["contact-form"]),
valid = true,
messages = [],
dfd = $.Deferred();
/*
* 클라이언트 확인 코드는 다음과 같습니다.
*/
if (!valid) {
dfd.resolve({
success: false,
오류: 메시지
})
} else {
form.ajaxSubmit({
dataType: "json",
성공: dfd.resolve,
error : dfd.reject
});
}
return dfd.promise();
}
saveContact(row).then(function (response) {
if (response) .success) {
// 클라이언트 확인이 통과되었으며 데이터가 성공적으로 저장되었습니다
} else {
// 클라이언트 확인 실패
// 오류 메시지 출력
}
}) .fail (function (err) {
// AJAX 요청 실패
})
saveContact() 함수는 먼저 양식 데이터의 유효성을 확인한 후 유효성 상태를 변수가 유효합니다. 유효성 검사가 실패하면 직접 연기가 트리거됩니다(성공 상태 코드와 오류 정보가 포함된 JS 개체를 매개 변수로 콜백 함수에 전달). 확인이 통과되면 데이터가 서버에 제출되고 AJAX가 성공적으로 완료된 후 지연된 개체가 트리거됩니다. failure()는 404, 500 등을 처리합니다. AJAX 요청이 성공적으로 완료되는 것을 방해할 수 있는 HTTP 상태 코드입니다.
관찰할 수 없는 작업
Deferred는 비동기 작업이든 동기 작업이든 작업과 작업 처리 기능을 분리하는 데 매우 유용합니다. 작업은 약속을 반환할 수도 있지만 문자열, 개체 또는 기타 유형을 반환할 수도 있습니다.
이 예에서는 "Lanch Application" 링크를 처음 클릭하면 AJAX 요청이 서버로 전송되고 현재 타임스탬프가 반환됩니다. 이 타임스탬프는 링크의 데이터 캐시에 저장됩니다. 링크를 다시 클릭하면 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 ('클릭', 함수(이벤트) {
event.preventDefault();
$.when(startTask(this)).done(함수(타임스탬프) {
$('#status'). html('
loadApplication()
});
$.when()이 첫 번째 매개변수에 약속 함수가 없음(따라서 관찰할 수 없음)을 발견하면 새로운 지연된 객체를 생성하고 지연된 객체를 트리거하며 약속 읽기 전용 객체를 반환합니다. 따라서 관찰할 수 없는 작업은 $.when()에 전달될 수도 있습니다.
한 가지 주의할 점은 객체 자체에 promise 함수가 있는 경우 이 객체를 deferred 객체로 사용할 수 없다는 것입니다. jQuery는 약속 함수가 있는지 확인하여 개체가 연기되는지 여부를 결정하지만, jQuery는 약속이 실제로 사용 가능한 개체를 반환하는지 여부를 확인하지 않습니다. 따라서 다음 코드는 오류가 발생합니다.
}
}
$.when(obj).then(fn)
결론(결론)
Deferred는 비동기 작업을 처리하는 새롭고 강력한 방법을 제안합니다. 코드를 콜백 함수로 구성하는 기존 방식과 달리, 새로운 지연된 객체를 사용하면 언제든지(작업이 끝난 후에도) 여러 콜백 함수를 바인딩할 수 있으며 이러한 콜백 함수는 선입선출 방식으로 호출됩니다. 방법. 이 기사의 정보는 이해하기 어려울 수 있지만, 일단 지연된 개체의 사용을 익히면 비동기적으로 실행되는 코드를 구성하는 것이 매우 쉽다는 것을 알게 될 것입니다.
재인쇄 시 출처를 밝혀주세요.