jQuery1.5에서 지연된 객체를 사용하고 돋보기로 Promise_jquery를 살펴봅니다.

WBOY
풀어 주다: 2016-05-16 18:09:39
원래의
804명이 탐색했습니다.
소개

jQuery 1.5의 Deferred 사용에 대한 클래식 기사 (여기 번역 참조)에 다음 설명이 있습니다.

$.ajax()는 다른 지연 관련 메서드로 구성된 개체를 반환합니다. promise()에 대해 설명했지만 then(), Success(), error() 및 기타 여러 메서드도 찾을 수 있습니다. 그러나 지연된 개체의 상태를 확인하는 데 사용할 수 있는 promise, 콜백 바인딩 메서드, isRejected() 및 isResolved() 메서드에만 액세스할 수 있습니다.
그 이유는 무엇입니까? 전체 객체를 반환하지 않습니까? 그렇다면 작업을 방해하고 지연된 항목을 실용적으로 "해결"하여 AJAX 요청이 완료되기 전에 모든 바인딩된 콜백이 실행되도록 할 수 있습니다. 전체 패러다임을 깨뜨릴 가능성이 있으므로 dfd.promise()만 반환하세요.


이 구절은 매우 혼란스러워서 이해하기 전에 여러 번 읽었습니다. 일반적인 의미는 다음과 같습니다.
$.ajax()는 객체(기본 XMLHttpRequest를 캡슐화한 jqXHR)를 반환합니다. 이 객체에는 promise(), then(), Success()와 같은 지연 관련 함수가 포함되어 있습니다. , 오류(), isRejected(), isResolved().
그런데 거기에는solve(), ResolveWith(), Reject(), RejectWith() 함수가 없고 이러한 함수는 지연 객체 프로세스를 변경하는 데 사용된다는 것을 알고 계셨습니까? 즉, $.ajax()는 읽기 전용 지연 객체 를 반환합니다.

다음 에리킨드는 수사적인 어조로 지연된 객체 전체를 반환하지 않고 읽기 전용 지연 객체만 반환하는 이유를 물었습니다.
완전한 지연된 객체가 반환되면 외부 프로그램은 지연된 객체의 콜백 함수(resolve)가 AJAX 요청이 끝나기 전에 트리거될 가능성이 매우 높습니다. AJAX 자체의 논리에.
따라서 실수로 작업의 내부 흐름을 변경하는 것을 방지하려면 지연된 읽기 전용 버전(dfd.promise())만 반환해야 합니다.


$.ajax() 및 $.Deferred()에서 반환된 지연된 개체의 차이점을 설명하려면 다음 예를 참조하세요.
코드 복사 코드는 다음과 같습니다.

// 지연된 개체의 모든 메서드 배열
var 메서드 = 'done,resolveWith,resolve ,isResolved,then,fail, RejectWith,reject,isRejected,promise'.split(','),
method,
ajaxMethods = [],
onlyInDeferredMethods = []
for (메서드) in $.ajax()) {
if ($.inArray(메소드, 메소드) !== -1) {
ajaxMethods.push(메소드)
}
}

for ($ .Deferred()의 메소드) {
if ($.inArray(메소드, 메소드) !== -1 && $.inArray(메소드, ajaxMethods) === -1) {
onlyInDeferredMethods.push(method);
}
}
// $.Deferred()에는 있지만 $.ajax()에는 없는 지연된 관련 메서드 목록은 다음과 같습니다.
// [ "resolveWith", "resolve" , "rejectWith", "reject"]
console.log(onlyInDeferredMethods);

부정 교육 자료
$.ajax( )에는 해결(), 해결하기() 가 포함되어 있는데 어떤 영향을 미칠 수 있나요?
예를 사용하여 설명하겠습니다. 먼저 에리키네스의 원본 텍스트의 첫 번째 예를 살펴보겠습니다.
코드 복사 코드는 다음과 같습니다:

// $.get, 비동기 AJAX 요청
var req = $.get('./sample.txt').success(function (response) {
console.log('AJAX 성공');
}).error(function () {
console.log('AJAX 오류');

/ / AJAX 콜백 함수를 하나 더 추가합니다. AJAX가 지금 종료되었거나 아직 종료되지 않았을 수 있습니다
// $.ajax에는 지연 지원이 내장되어 있으므로 다음과 같이 작성할 수 있습니다
req.success (함수(응답) {
console.log('AJAX 성공2');
})

console.log('END')

실행 결과는 다음과 같습니다.
END -> ; AJAX 성공 -> AJAX 성공2

아래 jQuery1.5 소스 코드를 수정하고 $.ajax 반환 값에 대한solve() 및solveWith() 함수를 추가합니다. ():

코드 복사 코드는 다음과 같습니다.
// 유예 첨부
deferred.promise( jqXHR );
jqXHR.success = jqXHR.done;
jqXHR.error = jqXHR.complete = CompleteDeferred.done
// jQuery 소스 코드에는
jqXHR이 없습니다.
jqXHR.resolveWith


그런 다음 다음 코드를 실행하세요.
코드 복사 코드는 다음과 같습니다.

// $ .get, 비동기 AJAX 요청
var req = $.get('./sample.txt').success(function (response) {
console.log('AJAX 성공');
} ).error(function () {
console.log('AJAX 오류');
})

req.resolve(); / AJAX 콜백 함수를 하나 더 추가합니다. AJAX가 지금 종료되었거나 아직 종료되지 않았을 수 있습니다
// $.ajax에는 지연 지원이 내장되어 있으므로 다음과 같이 작성할 수 있습니다
req.success (함수(응답) {
console.log('AJAX 성공2');
})

console.log('END')


이때 실행 결과는 다음과 같습니다.
AJAX 성공 -> AJAX 성공2 -> END

즉, 실제 AJAX 요청이 끝나기 전에 성공 콜백 함수가 실행되어 오류가 발생합니다.

이 모든 것을 더 명확하게 확인하기 위해 일부 가짜 매개변수를 성공 콜백 함수에 수동으로 전달합니다.


// $.get, 비동기 AJAX 요청
var req = $.get('./sample.txt').success(function ( response) {
console.log('AJAX 성공(' 응답 ')')

req.resolve('가짜 데이터')

/ / 또 다른 AJAX 콜백 함수를 추가합니다. AJAX가 지금 종료되었거나 아직 종료되지 않았을 수 있습니다
// $.ajax에는 지연 지원이 내장되어 있으므로 다음과 같이 작성할 수 있습니다
req.success( 함수(응답) {
console.log('AJAX 성공2(' 응답 ')')
});

console.log('END');
이때 실행 결과는 다음과 같습니다.
AJAX 성공(가짜 데이터) -> AJAX 성공2(가짜 데이터) ->

코드 분석
jQuery 코드를 살펴보기 전에 , 다음 내용에 대한 jQuery.promise 문서를 살펴보겠습니다.
deferred.promise() 메서드를 사용하면 비동기 함수가 다른 코드가 내부 요청의 진행 상황이나 상태를 방해하는 것을 방지할 수 있습니다. Promise는 필요한 Deferred 메서드만 노출합니다. 추가 핸들러를 연결하거나 상태(done, failure, isResolved 및 isRejected)를 결정하지만 상태를 변경하는 핸들러(resolve,ject,resolveWith 및 recognitionWith)는 결정하지 않습니다.
Deferred를 생성하는 경우 유지하세요. 특정 시점에서 해결되거나 거부될 수 있도록 Deferred에 대한 참조 deferred.promise()를 통해 Promise 객체만 반환하므로 다른 코드에서 콜백을 등록하거나 현재 상태를 검사할 수 있습니다.

대략 말하면 deferred입니다. .promise()는 다른 코드가 비동기 작업의 내부 흐름을 수정하는 것을 방지하는 데 사용됩니다. Promise 객체는 콜백 함수와 상태 감지용 함수만 공개적으로 추가하지만 상태 수정용 함수는 포함하지 않습니다.
지연된 객체를 수동으로 생성하는 경우 지연된 객체에 대한 참조를 유지하여 콜백 함수를 트리거하도록 상태를 수정해야 합니다. 그러나 반환 값은 deferred.promise()여야 합니다. 그러면 외부 프로그램이 콜백 함수를 추가하거나 상태를 감지할 수 있지만 상태를 수정할 수는 없습니다.

이 시점에서는 누구나 Promise에 대해 명확히 이해하고 있어야 합니다. 다음 두 코드는 정확히 동일한 기능을 수행합니다.




코드 복사
코드는 다음과 같습니다. 🎜> function getData() { return $.get('/foo/') }
function showDiv() {
// 올바른 코드 . 권장 사례.
return $.Deferred(function (dfd) {
$('#foo').fadeIn(1000, dfd.resolve);
}).promise()
}

$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('애니메이션과 AJAX 요청이 모두 완료되었습니다!');
});






코드 복사

코드는 다음과 같습니다. function getData( ) { return $.get('/foo/'); }
function showDiv() {
// 올바른 코드입니다. 이는 권장되지 않습니다.
return $.Deferred(function (dfd) {
$('#foo').fadeIn(1000, dfd.resolve);
})
}

$ .when(getData(), showDiv()).then(function (ajaxResult) {
console.log('애니메이션과 AJAX 요청이 모두 완료되었습니다!');
}); 🎜>
위의 두 코드 조각은 동일한 작업을 수행하고 두 번째 코드 조각이 더 간결해 보이지만 두 번째 코드 조각은 권장되는 접근 방식이 아닙니다.
작업(showDiv) 자체의 상태 변경은 작업 내에서 유지되어야 하고 외부 세계에 노출될 필요가 없기 때문에 읽기 전용 지연 객체만 노출하면 됩니다. 약속하다.

마지막으로 Deferred 관련 소스코드를 살펴보겠습니다.
코드 복사 코드는 다음과 같습니다. 다음은 다음과 같습니다.

//Promise 관련 메서드 배열
promiseMethods = "then done failure isResolved isRejected promise".split( " " ),

jQuery.extend(
// 지연된 객체 완성(콜백 큐 2개 포함)
Deferred: function (func) {
var deferred = jQuery._Deferred(),
failDeferred = jQuery._Deferred(),
promise;
// then, promise 및 오류 관련 지연 메서드 추가
jQuery.extend(deferred, {
then: function (doneCallbacks, failureCallbacks) {
deferred.done(doneCallbacks).fail(failCallbacks );
이것을 반환합니다.
},
fail: 실패Deferred.done,
rejectWith: 실패Deferred.resolveWith,
reject: 실패Deferred.isResolved,
// 지연된 객체의 읽기 전용 복사본을 반환합니다
// obj가 매개변수로 전달되면 promise 관련 메서드가 이 obj에 추가됩니다
promise: function(obj) {
if (obj == null) {
if (promise) {
return promise;
}
promise = obj = {}
}
var i = promiseMethods.length;
while (i- -) {
obj[promiseMethods[i]] = deferred[promiseMethods[i]]
}
return obj;
}
}) 🎜>// 콜백 함수 대기열이 하나만 있는지 확인하세요. 이는 작업이 성공하거나 실패함을 의미합니다.
deferred.done(failDeferred.cancel).fail(deferred.cancel)// 취소 함수 삭제
deferred.cancel;
// 현재 생성된 함수를 매개변수로 전달합니다.
if (func) {
func.call(deferred, deferred); >}
return deferred;
});


위 코드가 읽기 어렵다면 간단하게 유사한 코드를 작성해도 됩니다.



코드 복사
코드는 다음과 같습니다. Arr = function () { var items = [ ],
promise,
arr = {
add: function (item) {
items.push(item)
},
length: function () {
return items.length;
},
clear: function () {
items = []
},
promise: function () {
if (promise) {
return promise;
}
var obj = promise = {};
obj.add = arr.add;
obj.length = arr.length = arr .promise;
return obj;
}
};
return arr;
}


위 코드는 Arr을 정의합니다. add(), length(),clear(), promise()와 같은 일부 메소드를 포함하는 배열 객체입니다.
promise()가 현재 Arr 객체의 복사본을 반환하는 경우 요소를 여기에 추가할 수만 있고 내부 배열을 지울 수는 없습니다.



코드 복사
코드는 다음과 같습니다. var arr = Arr(); >arr.add(1); arr.add(2); console.log(arr.length()); // 0
console.log(arr.length());
var arr()
arr.add(1)
arr.add(2); // 2
console.log(arr.length());
var promise = arr.promise()
promise.add(3)
🎜>/ / 4
console.log(promise.length());
// 오류: TypeError: promise.clear는 함수가 아닙니다.
promise.clear();
deferred.promise() 및 deferred.promise().promise()
동일한 기능을 수행하는 앞서 언급한 두 코드를 기억하시나요?




코드 복사


코드는 다음과 같습니다.

function getData() {
return $.get ('/foo/');
}
function showDiv() { // 여기서 promise()를 반환하거나 지연된 객체를 직접 반환하면 코드가 올바르게 실행됩니다. return $.Deferred(function (dfd) { $('#foo').fadeIn(1000, dfd.resolve); }).promise() }
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('애니메이션과 AJAX 요청이 모두 완료되었습니다!');
});


그럼 이 두 가지 방법이 왜 작동하는지 생각해보신 적 있으신가요?
jQuery의 소스 코드를 살펴보면 $.when(obj1, obj2, ...)이 obj1.promise()를 얻기 위해 내부적으로 구현되어 있음을 알 수 있습니다.




코드 복사


코드는 다음과 같습니다.

if ( object && jQuery.isFunction( object.promise ) ) {
object.promise().then( iCallback(lastIndex), deferred.reject )
}

위의 showDiv 반환 결과를 살펴보겠습니다.
연기된 객체인 경우 $.when()은 다음과 같은 방식으로 Promise를 가져옵니다.
$.Deferred().promise()

deferred.promise() 객체인 경우 $.when()은 다음과 같은 방식으로 Promise를 가져옵니다.
$.Deferred().promise().promise()

그 뜻은 다음과 같습니다: $.Deferred().promise() === $.Deferred().promise().promise()
예제를 통해 아이디어를 검증해 보겠습니다.
코드 복사 코드는 다음과 같습니다.

var deferred = $.Deferred(),
promise = deferred.promise( );
/ / true
promise === promise.promise();
// true
promise === promise.promise().promise().promise(); >
물론 이 결과는 Deferred의 소스 코드를 직접 보면 다음과 같은 결과를 쉽게 알 수 있습니다.

복사 code 코드는 다음과 같습니다.
promise: function (obj) {
if (obj == null) {
// 여기서, promise가 이미 존재하는 경우(.promise() 호출) 다시 생성되지 않습니다.
if (promise) {
return promise;
}
promise = obj = {}; }
var i = promiseMethods.length;
while (i--) {
obj[promiseMethods[i]] = deferred[promiseMethods[i]];
return obj;
}


요약
1. deferred.promise()는 지연된 객체의 읽기 전용 속성을 반환합니다.
2. 작업은 지연된 객체를 반환하지 않고 deferred.promise() 객체를 반환하는 것이 좋습니다. 이런 방식으로 외부 당사자는 업무의 내부 프로세스를 임의로 변경할 수 없습니다.
3. deferred.promise() === deferred.promise().promise() (우리는 코드 추론과 소스 코드 분석이라는 두 가지 관점에서 결론을 내렸습니다.)

이 글은 Sanshengshi가 작성했습니다. 블로그파크에 처음 게재된 블로그의 원본이며, 재인쇄 시 출처를 표기해 주시기 바랍니다.
관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!