(function( jQuery ) {
function handlerQueueMarkDefer( elem, type, src ) {
var deferDataKey = 유형 "defer",
queueDataKey = 유형 "queue",
markDataKey = type "mark",
defer = jQuery._data( elem, deferDataKey )
if ( defer &&
( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
// 하드 코딩된 콜백이 먼저 실행되도록 공간을 제공하고
// 결국에는 표시/
setTimeout( function() {
if ( !jQuery._data( elem, queueDataKey ) &&
!jQuery._data( elem, markDataKey ) ) {
jQuery.removeData 요소에 다른 것을 대기열에 넣습니다. ( elem, deferDataKey, true );
}
}, 0 )
}
}
jQuery.extend({
_mark: function( elem, type ) {
if ( elem ) {
type = ( type || "fx" ) "mark"
jQuery._data( elem, type, (jQuery._data( elem, 유형 ) || 0) 1 )
}
},
_unmark: function( force, elem, type ) {
if ( force !== true ) {
type = elem ;
요소 = 강제
강제 = 거짓;
}
if ( elem ) {
type = type || "FX";
var 키 = "mark" 입력,
count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
if ( count ) {
jQuery._data( elem, key, count );
} else {
jQuery.removeData( elem, key, true );
handleQueueMarkDefer( elem, type, "mark" );
}
}
},
queue: function( elem, type, data ) {
var q;
if ( elem ) {
type = ( type || "fx" ) "큐";
q = jQuery._data( elem, type );
// 단순한 조회인 경우 빨리 나가서 대기열 제거 속도를 높이세요.
if ( data ) {
if ( !q || jQuery.isArray(data) ) {
q = jQuery. _data( elem, type, jQuery.makeArray(data) );
} else {
q.push( 데이터 );
}
}
q를 반환 || [];
}
},
큐 제거: 함수( elem, 유형 ) {
유형 = 유형 || "FX";
var queue = jQuery.queue( elem, type ),
fn = queue.shift(),
hooks = {};
// fx 대기열이 대기열에서 제거되면 항상 진행 센티널을 제거하세요.
if ( fn === "inprogress" ) {
fn = queue.shift();
}
if ( fn ) {
// fx 대기열이 삭제되는 것을 방지하기 위해 진행 센티널을 추가합니다
// 자동으로 대기열에서 제거됩니다
if ( type === "fx" ) {
queue.unshift( "진행 중" );
}
jQuery._data( elem, 유형 ".run", 후크 );
fn.call( elem, function() {
jQuery.dequeue( elem, type );
}, Hooks );
}
if ( !queue.length ) {
jQuery.removeData( elem, type "queue " type ".run", true );
handleQueueMarkDefer( elem, type, "queue" );
}
}
});
jQuery.fn.extend({
queue: function( type, data ) {
var setter = 2;
if ( typeof type !== "string" ) {
data = type;
type = "fx";
setter--;
}
if (args.length < setter ) {
return jQuery.queue( this[0], type ) ;
}
return data === 정의되지 않음 ?
this :
this.each(function() {
var queue = jQuery.queue( this, type, data );
if ( type === "fx" && queue[0] !== "inprogress" ) {
jQuery.dequeue( this, type )
}
});
dequeue: function( type ) {
return this.each(function() {
jQuery.dequeue( this, type );
}); 허가를 받아 Clint Helfers의 플러그인을 기반으로 합니다.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx"
return this.queue( type, function( next, Hooks ) {
var timeout(next, time );
hooks.stop = function() {
clearTimeout( timeout )
}),
clearQueue: function( type ) {
return this.queue( type || "fx", [] );
},
// 특정 유형의 대기열이 비워질 때 Promise를 확인합니다
// (fx는 기본 유형입니다)
promise: function( type, object ) {
if ( typeof type !== "string" ) {
object = type;
유형 = 정의되지 않음;
}
유형 = 유형 || "FX";
var defer = jQuery.Deferred(),
elements = this,
i = elements.length,
count = 1,
deferDataKey = type "defer",
queueDataKey = 유형 "대기열",
markDataKey = 유형 "마크",
tmp;
functionsolve() {
if ( !( --count ) ) {
defer.resolveWith( elements, [ elements ] );
}
}
while( i-- ) {
if (( tmp = jQuery.data( elements[ i ], deferDataKey, unundefined, true ) ||
( jQuery.data ( 요소[ i ], queueDataKey, 정의되지 않음, true ) ||
jQuery.data( 요소[ i ], markDataKey, 정의되지 않음, true ) ) &&
jQuery.data( 요소[ i ], deferDataKey, jQuery. 콜백( "한 번 메모리" ), true ) )) {
count ;
tmp.add( 해결 );
}
}
해결();
return defer.promise(객체);
}
});
})( jQuery );
현재 Hook 메커니즘은 실제로 jQuery 내에서 확산되었습니다. 1.5는 CSS 모듈의 cssHooks, 1.6은 속성 모듈의 attrHooks, propHooks, boolHooks, nodeHooks, 1.7은 이벤트 모듈의 fixHooks, keyHooks, mouseHooks, 1.8은 큐입니다. 모듈의 _queueHooks로 인해 큐의 무게가 마침내 감소했습니다.
코드 보기?//1.8
jQuery.extend ({
queue: function( elem, type, data ) {
var queue;
if ( elem ) {
type = ( type || "fx" ) "queue";
queue = jQuery._data( elem, type );
// 단순한 조회인 경우 빠르게 나가서 대기열 제거 속도를 높입니다.
if ( data ) {
if ( !queue | | jQuery.isArray( data) ) {
queue = jQuery._data( elem, type, jQuery.makeArray(data) )
} else {
queue.push( data );
}
큐 반환 ||
}
},
큐 제거: function( elem, type ) {
type = "fx"; var queue = jQuery.queue( elem, type ),
fn = queue.shift(),
hooks = jQuery._queueHooks( elem, type ),
next = function() {
jQuery .dequeue( elem, type );
};
// fx 대기열이 제거되면 항상 진행 센티널을 제거합니다.
if ( fn === "inprogress" ) {
fn = 대기열 .shift();
}
if ( fn ) {
// fx 대기열이 자동으로 대기열에서 제거되는 것을 방지하기 위해 진행 센티널을 추가합니다
// if ( type === " fx" ) {
queue.unshift( "inprogress" );
}
// 마지막 대기열 중지 기능 지우기
delete Hooks.stop;
fn.call( elem, next , 후크 );
}
if ( !queue.length && 후크 ) {
hooks.empty.fire();
}
},
// 공개용 아님 소비 - queueHooks 객체를 생성하거나 현재 객체를 반환합니다.
_queueHooks: function( elem, type ) {
var key = type "queueHooks"
return jQuery._data( elem, key ) || ._data( elem, key, {
empty: jQuery.Callbacks("한 번 메모리").add(function() {
jQuery.removeData( elem, type "queue", true );
jQuery .removeData( elem, key, true );
})
});
}
})
jQuery.fn.extend({
queue: function( type, data) {
var setter = 2;
if ( typeof type !== "string" ) {
data = type;
setter--; 🎜>}
if (args.length < setter ) {
return jQuery.queue( this[0], type )
}
return data === 정의되지 않음
this :
this .each(function() {
var queue = jQuery.queue( this, type, data );
// 이 큐에 대한 후크 확인
jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) {
jQuery.dequeue( this, type )
}
},
dequeue: function( type ) {
return this.each(function() {
jQuery.dequeue( this, type );
}),
// 허가를 받아 Clint Helfers의 플러그인을 기반으로 합니다.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
지연: 함수( 시간, type) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time
type = type || "fx"
return this.queue( 다음, 후크 ) {
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout )
}); >},
clearQueue: function( type ) {
return this.queue( type || "fx", [] )
},
// 대기열이 실행될 때 Promise를 가져옵니다. 특정 유형
// 비어 있습니다(fx는 기본 유형입니다)
promise: function( type, obj ) {
var tmp,
count = 1,
defer = jQuery.Deferred (),
elements = this,
i = this.length,
resolve = function() {
if ( !( --count ) ) {
defer.resolveWith( elements, [ 요소 ] );
}
};
if ( typeof type !== "string" ) {
obj = type;
}
type = type || "fx";
while( i-- ) {
if ( (tmp = jQuery._data( elements[ i ], type "queueHooks" )) && tmp.empty ) {
count ;
tmp.empty.add( 해결 );
}
}
resolve()
return defer.promise( obj ); ;
동시에 애니메이션 모듈은 세 번째 대규모 재구성을 시작했으며 후크 Tween.propHooks도 있습니다. 두 개의 객체가 더 있고, Animation은 비동기 대기열을 반환하고, Tween은 이전 Fx 객체와 동일한 단일 스타일이나 속성의 변경 사항을 처리하는 데 사용됩니다. animate는 1.72에서는 거의 100줄에 달했습니다. jQuery는 후크 메커니즘과 차별화를 사용하여 몇 가지 새로운 개체를 만들고 몇 가지 거대한 메서드를 재구성합니다. 이제 매우 긴 메소드는 노드 모듈과 콜백 모듈에만 국한됩니다.
코드 복사
코드는 다음과 같습니다.
animate: function( prop, speed, easing, callback ) {
var empty = jQuery.isEmptyObject( prop ),
optall = jQuery.speed( speed, easing, callback ),
doAnimation = function() {
// 속성별 여유가 손실되지 않도록 prop 복사본에 대해 작업
var anim = Animation( this, jQuery.extend( {}, prop ), optall ) ;
// 빈 애니메이션은 즉시 해결됩니다.
if ( 비어 있음 ) {
anim.stop( true )
}
return 비어 있음 || false ?
this.each( doAnimation ) :
this.queue( optall.queue, doAnimation )
},
지금까지 모든 비동기 작업은 jQuery를 비동기 대기열의 "하위 클래스" 또는 "변형"으로 변환하는 것이 더 적합합니다. Promise나 Delay, 다양한 특수 효과 메소드를 실행한 후 domReady, animation, AJAX, jQuery 객체 등이 있습니다. 따라서 모든 비동기 작업은 약속의 보호를 받으며 비동기 프로그램은 동기화처럼 작성됩니다.