ホームページ >ウェブフロントエンド >jsチュートリアル >jquery1.83_jquery より前の非同期キューに関連するすべてのモジュールの詳細な紹介

jquery1.83_jquery より前の非同期キューに関連するすべてのモジュールの詳細な紹介

WBOY
WBOYオリジナル
2016-05-16 17:48:181172ブラウズ

jQuery在1.5引入了Deferred对象(异步列队),当时它还没有划分为一个模块,放到核心模块中。直到1.52才分割出来。它拥有三个方法:_Deferred, Deferred与when。

出于变量在不同作用域的共用,jQuery实现异步列队时不使用面向对象方式,它把_Deferred当作一个工厂方法,返回一个不透明的函数列队。之所以说不透明,是因为它的状态与元素都以闭包手段保护起来,只能通过列队对象提供的方法进行操作。这几个方法分别是done(添加函数),resolveWith(指定作用域地执行所有函数),resolve(执行所有函数),isResolved(判定是否已经调用过resolveWith或resolve方法),cancel(中断执行操作)。但_Deferred自始至终都作为一个内部方法,从没有在文档中公开过。

Deferred在1.5是两个_Deferred的合体,但1+1不等于2,它还是做了增强。偷偷爆料,Deferred本来是python世界大名鼎鼎的Twisted框架的东西,由早期七大JS类库中的MochiKit取经回来,最后被dojo继承衣钵。jQuery之所以这样构造Deferred,分明不愿背抄袭的恶名,于是方法改得一塌糊涂,是jQuery命名最差的API,完全不知所云。它还加入当时正在热烈讨论的promise机制。下面是一个比较列表:

dojo jQuery 注解
addBoth then 同时添加正常回调与错误回调
addCallback done 添加正常回调
addErrback fail 添加错误回调
callback done 执行所有正常回调
errback reject 执行所有错误回调
doneWith 在指定作用域下执行所有正常回调,但dojo已经在addCallback上指定好了
rejectWith 在指定作用域下执行所有错误回调,但dojo已经在addErrback上指定好了
promise 返回一个外界不能改变其状态的Deferred对象(外称为Promise对象)

jQuery の when メソッドは、コールバック コールバックを実装するために使用されます。つまり、他のコールバックは、いくつかの異なるキューが実行された後にのみ実行されます。これらの後のコールバックも、done、when、fail を使用して追加されますが、when によって返されるオブジェクトには、ユーザーがその実行を制御する機能が追加されています。現時点では、これは Promise と呼ばれるものであり、コールバックを追加し、ユーザーがそのステータスを確認できるようにすることだけを担当します。前のコールバックがトリガーされると、通常のコールバック キュー (遅延、Deferred メソッドの定義を参照) またはエラー コールバック キュー (failDeferred) に自然に入力されます。しかし、このように言うと、非同期プログラミングの経験がない人にとっては、間違いなく混乱して聞こえるでしょう。例を見てみましょう。
コードをコピー コードは次のとおりです。

$.when({aa:1} , {aa :2}).done(function(a,b){
console.log(a.aa)
console.log(b.aa)
}); >
1,2を直接出力します。 2 つの関数が渡されると、2 つの関数が返されます。したがって、通常のデータ型の場合、done メソッドと failed メソッドのコールバックには、前の when のパラメータと同じ数のパラメータが含まれます。


function fn(){
return 4;
}
関数ログ{
window.console && console.log(s)
}
$.when( { num:1 }, 2, '3' , fn( ) ).done(function(o1, o2, o3, o4){
log(o1.num);
log(o2);
log(o3);
log( o4);
});


それぞれの非同期結果を取得したい場合は、resolve、resolveWith、reject、rejectWith を使用して渡す必要があります。


var log = function(msg){
window .console && console.log(msg)
}
function asyncThing1(){
var dfd = $.Deferred();
setTimeout(function(){
log() 'asyncThing1 は完了したようです...');
dfd.resolve('1111')
},1000);
return
}
関数asyncThing2() {
var dfd = $.Deferred();
setTimeout(function(){
log('asyncThing2 は完了したようです...');
dfd.resolve(' 222') ;
},1500);
return dfd.promise();
function asyncThing3(){
var dfd = $.Deferred(); (function( ){
log('asyncThing3 が完了したようです...');
dfd.resolve('333');
},2000);
return dfd.promise( );
}
/* 実行します */
$.when( asyncThing1(), asyncThing2(), asyncThing3() ).done(function(res1, res2, res3){
log ('すべて完了!');
log(res1 ', ' res2 ', ' res3);


非同期キューは最初は誰も使用していませんでした今は誰も使っていない(概念が抽象的すぎる、メソッド名が悪すぎる)ため、社内でのみ作成および販売できます。まず最初に触れられるのは行列です。キュー モジュールは、コミュニティを引き付けるために設計された 1.4 の遅延プラグインであり、データ モジュールとは特別に区別されていますが、データはイベントからモジュール的に分離されています。新しい jQuery モジュールが常に誕生するのは、ユーザーが既存の API の制限に不満を抱いているためです。最初のキュー モジュールのソース コード:



コードをコピーします
コードは次のとおりです:

jQuery.extend({
queue: function( elem, type, data ) {
if ( !elem ) {
return;
}
type = (type || "fx") "queue";
var q = jQuery.data( elem, type ); // これが単なる検索の場合は、デキューを高速化します。
if ( !data ) {
return q ||
}
if ( !q || jQuery.isArray(data) ) {
q = jQuery.data( elem, type, jQuery.makeArray(データ) );
} else {
q.push( data );
}
デキュー: function( elem, type ) {
type = type || "fx";
var queue = jQuery.queue( elem, type ), fn = queue.shift();
// fx キューがデキューされた場合は、常に進行状況センチネルを削除します🎜>if ( fn === "inprogress" ) {
fn = queue.shift();
}
if ( fn ) {
// fx キューを防ぐために進行状況監視を追加します
// 自動的にデキューされないようにします
if ( type === "fx" ) {
queue.unshift("inprogress");
}
fn.call(elem, function( ) {
jQuery.dequeue(elem, type)
}
}
});
jQuery.fn.extend({
queue: function( type, data ) {
if ( typeof type !== "string" ) {
data = type;
type = " fx";
}
if ( data === unknown ) {
return jQuery.queue( this[0], type );
}
return this.each(function( i , elem ) {
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 によるプラグインに基づいています。 php/2009/07/jquery-delay/
遅延: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[time] ||
type = type || "fx";
return this.queue( type, function() {
var elem = this;
setTimeout(function() {
jQuery.dequeue( elem, type );
}, 時間 );
});
},
clearQueue: function( type ) {
return this.queue( type || "fx", }
});


1.6 は、_mark、_unmark、promise を追加しました。queue は関数に属する 1 つの特別なエリアであり、アニメーションの実行を目的としています。_mark はそれぞれに問題があり、実行を列挙します (これらは、実行されたアニメーションの実行後に、いくつかの回帰 (またはアニメーション) を実行することを約束します。 >复制代码


代码如下:

(function( jQuery ) {
function handleQueueMarkDefer( elem, type, src ) {
//清空记录deferred个数の字段,関数数列队与异步列队
var deferDataKey = type "defer",
queueDataKey = タイプ "キュー",
markDataKey = タイプ "マーク",
defer = jQuery.data( elem, deferDataKey, unknown, true );
if ( defer &&
( src === "queue" || !jQuery.data( elem, queueDataKey, unknown, true ) ) &&
( src === "mark" || !jQuery.data( elem, markDataKey, unknown , true ) ) ) {
// 最初にハードコードされたコールバックが起動するための余地を与えます
// そして最終的に要素に何か他のものをマーク/キューに入れます
setTimeout( function() {
if ( !jQuery.data( elem, queueDataKey, unfineed, true ) &&
!jQuery.data( elem, markDataKey, unknown, true ) ) {
jQuery.removeData( elem, deferDataKey, true ); .resolve();
}
}, 0 );
}
}
jQuery.extend({
_mark: function( elem, type ) {
if ( elem ) {
type = (type || "fx") "mark";//创建一以後缀的字段,记录此列队中个数用
jQuery.data( elem, type, (jQuery.data(elem,type,unknown,true) || 0) 1、真);
}
},
_unmark: function(force, elem, type ) {
if (force !== true ) {
type = elem;
elem = 力;
強制 = false;
}
if ( elem ) {
type = タイプ || "fx";
var key = type "mark",
//让个数减1,如果第一个パラメータがtrue,就强逼减至0
count = Force ? 0 : ( (jQuery.data( elem, key, unknown, true) || 1 ) - 1 );
if ( count ) {
jQuery.data( elem, key, count, true );
} else {//場合結果が 0,就移除它
jQuery.removeData( elem, key, true );
handleQueueMarkDefer( elem, type, "mark" );
}
}
},
queue: function( elem, type, data ) {
if ( elem ) {
type = (type || "fx") "queue ";
var q = jQuery.data( elem, type, unknown, true );
// これが単なる検索の場合は、すぐに出力してデキューを高速化します。
if ( data ) {
if ( !q || jQuery.isArray(data) ) {
q = jQuery. data( elem, type, jQuery.makeArray(data), true );
} else {
q.push( data );
}
}
return q || [];
}
},
デキュー: function( elem, type ) {
type = type || "fx";
var queue = jQuery.queue( elem, type ),
fn = queue.shift(),
defer;
// fx キューがデキューされた場合は、常に進行状況センチネルを削除します。
if ( fn === "inprogress" ) {
fn = queue.shift();
}
if ( fn ) {
// fx キューが実行されないように進行状況監視を追加します
// 自動的にデキューされます
if ( type === "fx" ) {
queue.unshift("進行中");
}
fn.call(elem, function() {
jQuery.dequeue(elem, type);
});
}
if ( !queue.length ) {
jQuery.removeData( elem, type "queue", true );
handleQueueMarkDefer( elem, type, "queue" );
}
}
});
jQuery.fn.extend({
queue: function( type, data ) {
if ( typeof type !== "string" ) {
data = type;
type = " fx";
}
if ( data === unknown ) {
return jQuery.queue( this[0], type );
}
return 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 によるプラグインに基づいています。 /07/jquery-lay/
遅延: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[time] ||
type = type || "fx";
return this.queue( type, function() {
var elem = this;
setTimeout(function() {
jQuery.dequeue( elem, type );
}, 時間 );
});
},
clearQueue: function( type ) {
return this.queue( type || "fx", [] );
//ハンドルjQuery对象装进一异步列队,允许它在一系列アニメーション画中再実行之後绑定的回调
promise: function( type, object ) {
if ( typeof type !== "文字列" ) {
オブジェクト = タイプ;
タイプ = 未定義;
}
type = タイプ || "fx";
var defer = jQuery.Deferred()、
elements = this、
i = elements.length、
count = 1、
deferDataKey = type "defer"、
queueDataKey =タイプ「キュー」、
markDataKey = タイプ「マーク」;
関数solve() {
if ( !( --count ) ) {
defer.resolveWith( 要素, [ 要素 ] );
}
}
while( i-- ) {
//如果它之前已经使用过マーク解除、キュー等方法,那么我们将生成一新的遅延放进缓存系统
if (( tmp = jQuery.data( elements[ i ], deferDataKey, unknown, true ) ||
( jQuery.data( elements[ i ], queueDataKey, unknown, true ) ||
jQuery.data( elements[ i ], markDataKey, unknown, true ) ) &&
jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
count ;
tmp.done(resolve);
}
}
resolve();
return defer.promise();
}
});
})( jQuery );

jQuery.ajax モジュールも影響を受けます。$.
コードをコピー コードは次のとおりです。

deferred = jQuery.Deferred(),
completeDeferred = jQuery._Deferred(),
jqXHR ={/**/}
//....
deferred.promise( jqXHR );
jqXHR.success = jqXHR.done ;
jqXHR.error = jqXHR.fail;
jqXHR.complete = completeDeferred.done;

jQuery1.7 は、実際には遅延モジュールとは区別されます。以前の _Deferred バージョンを強化し、重複排除、ロック、false を返した場合の次のコールバックの実行の中断、クリア、その他の機能を追加しました。
コードをコピー コードは次のとおりです:

(function( jQuery ) {
// 文字列からオブジェクトのフラグ形式キャッシュ
var flagsCache = {};
// 文字列形式のフラグをオブジェクト形式のフラグに変換し、保存しますキャッシュ
function createFlags( flags ) {
var object = flagsCache[ flags ] = {},
i, length;
flags = flags.split( /s / ); i = 0、長さ = flags.length; i ) {
オブジェクト [ flags[i] ] = true;
オブジェクトを返します。
* 次のパラメータを使用してコールバック リストを作成します。
*
* フラグ:
* コールバック リストの動作を変更するスペースで区切られたオプションのフラグのリスト
*
* デフォルトでは、コールバック リストはイベント コールバック リストのように動作し、
* 複数回「起動」できます。
*
* 可能なフラグ:
*
* 1 回:コールバック リストは 1 回だけ起動できます (遅延のように)
*
* メモリ: 以前の値を追跡し、リストが最新の " ですぐに起動された後、追加されたコールバックを呼び出します
*
* 値 (Deferred と同様)
*
* 固有: コールバックを 1 回だけ追加できるようにします (リスト内に重複はありません)
*
* stopOnFalse: 呼び出しを中断しますコールバックが false を返した場合
*
*/
jQuery.Callbacks = function( flags ) {
// フラグを文字列形式からオブジェクト形式に変換します
// (チェックインします)最初にキャッシュします)
flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
var // 実際のコールバック リスト
list = [],
// 反復可能なリストの一連の火災呼び出し
stack = [],
// 最後の火災値 (忘れられないもの用) lists)
memory,
// リストが現在起動しているかどうかを知るためのフラグ
firing,
// 起動するための最初のコールバック (add と fireWith によって内部的に使用されます)
firingStart,
// 起動時のループの終了
firingLength,
// 現在起動しているコールバックのインデックス (必要に応じて削除で変更)
firingIndex,
// 1 つまたは複数のコールバックをリストに追加します
add = function( args ) {
var i,
length,
elem,
type,
actual;
for ( i = 0, length = args.length; i elem = args[ i ];
type = jQuery.type( elem );
if ( type === "array" ) {
// 再帰的に検査します
add( elem );
} else if ( type === "function" ) {
// ユニークモードではなく、コールバックが
if ( !flags.unique || !self.has( elem ) にない場合に追加します。 ) {
list.push( elem );
}
}
}
},
// コールバックを起動
fire = function( context, args ) {
args = args || [];
メモリ = !flags.memory || [ コンテキスト、引数 ];
発火 = true;
発射インデックス = 発射開始 || 0;
発射開始 = 0;
firelength = list.length;
for ( ; list && firingIndex < firingLength; firingIndex ) {
if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
memory = true; // 停止済みとしてマークします
break;
}
}
起動 = false;
if ( list ) {
if ( !flags.once ) {
if ( stack && stack.length ) {
memory = stack.shift();
self.fireWith( メモリ[ 0 ], メモリ[ 1 ] );
}
} else if (memory === true ) {
self.disable();
} else {
リスト = [];
}
}
},
// 実際のコールバック オブジェクト
self = {
// コールバックまたはコールバックのコレクションをリストに追加します
add: function( ) {
if ( list ) {
var length = list.length;
add( 引数 );
// 現在実行中のバッチにコールバックを追加する必要がありますか?
//
if ( 発火 ) {
発火長 = list.length;
// メモリを使用して、発火していない場合は
// 直前の
// 発火が停止されていない限り (stopOnFalse)
} else if ( メモリ && メモリ ! == true ) {
発射開始 = 長さ;
fire( メモリ[ 0 ], メモリ[ 1 ] );
}
}
これを返します;
},
// リストからコールバックを削除します。
remove: function() {
if ( list ) {
var args = argument,
argIndex = 0,
argLength = args.length;
for ( ; argIndex for ( var i = 0; i if ( args[ argIndex ] === list[ i ] ) {
// firingIndex と firingLength を処理します
if ( firing ) {
if ( i firingLength--;
if ( i firingIndex--;
}
}
}
// 要素を削除します
list.splice( i--, 1 );
// 何らかの unicity プロパティがある場合は、
// これを行う必要があるのは 1 回だけです。
if ( flags.unique ) {
break;
}
}
}
}
}
これを返します;
},
// 指定されたコールバックがリスト
にあるかどうかを制御します: function( fn ) {
if ( list ) {
var i = 0,
length =リストの長さ;
for ( ; i if ( fn === list[ i ] ) {
return true;
}
}
}
false を返します。
},
// リストからすべてのコールバックを削除します。
empty: function() {
list = [];
これを返します;
},
// リストに何も行わせないようにします。
disable: function() {
list = stack =memory = unknown;
これを返します;
},
// 無効になっていますか?
無効: function() {
return !list;
},
// リストを現在の状態にロックします。
lock: function() {
stack = unknown;
if ( !memory || メモリ === true ) {
self.disable();
}
これを返します;
},
// ロックされていますか?
ロック: function() {
return !stack;
},
// 指定されたコンテキストと引数を使用してすべてのコールバックを呼び出します
fireWith: function( context, args ) {
if ( stack ) {
if ( fire ) {
if ( !flags.once ) {
stack.push( [ context, args ] );
}
} else if ( !( flags.once &&memory ) ) {
fire( context, args );
}
}
これを返します;
},
// 指定された引数を使用してすべてのコールバックを呼び出します。
fire: function() {
self.fireWith( this, argument );
これを返します;
},
// コールバックがすでに少なくとも 1 回呼び出されているかどうかを確認するには
fired: function() {
return !!memory;
}
};
自分自身を返します。
};
})( jQuery );

この期間にはさらに小さな曲があります。jQuery ブロックは、内部公開者承認機構である、トピックを呼び出すモジュールの追加も予定していますが、これはパッケージ化が不十分であり、結果は未定です。 🎜>
复制代码代码如下:
(function( jQuery ) {
var topic = {},
sliceTopic = [].slice;
jQuery.Topic = function( id ) {
var callbacks,
method,
topic = id && topic[ id ];トピック ) {
callbacks = jQuery.Callbacks();
トピック = {
パブリッシュ: callbacks.fire、
サブスクライブ: callbacks.add、
アンサブスクライブ: callbacks.remove
} ;
if ( id ) {
トピック[ id ] = トピック;
}
jQuery.extend({
: function( id ) {
var topic = jQuery.Topic( id ),
args = slideTopic.call( argument, 1 );
topic.subscribe.apply( topic, args ); return {
トピック: トピック,
引数: args
};
},
unsubscribe: function( id ) {
var topic = id && id.topic ||トピック( id );
topic.unsubscribe.apply( topic, id && id.args ||
sliceTopic.call( argument, 1 ) );
publish: function( id ); {
var topic = jQuery.Topic( id );
topic.publish.apply( topic, slideTopic.call( argument, 1 ) );
}
});
})( jQuery );


は大量のコード移動コールバックを実行しますが、1.7 の遅延点は変わらず、より重くなり、3 つの関数の数列で構成されます。そして返されるのは Promise オブジェクトです。 ajax 那边は次のようになります:




代打

代打:
deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "oncememory" ), deferred.promise( jqXHR ); jqXHR.success = jqXHR.done; jqXHR.error = jqXHR.fail; jqXHR.complete = completeDeferred.add;

キュー那边も多少は変化しません。

(function( jQuery ) {
function handleQueueMarkDefer( 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) ) ) {
// 最初にハードコードされたコールバックが起動する余地を与えます
// そして最終的に mark/要素に何か他のものをキューに入れます
setTimeout( function() {
if ( !jQuery._data( elem, queueDataKey ) &&
!jQuery._data( elem, markDataKey ) ) {
jQuery.removeData ( elem, deferDataKey, true );
defer.fire();
}
}, 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 ;
要素 = 力;
力 = false;
}
if ( elem ) {
type = タイプ || "fx";
var key = type "mark"、
count = 強制 ? 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" ) "queue";
q = jQuery._data( elem, type );
// これが単なる検索の場合は、すぐに出力してデキューを高速化します。
if ( data ) {
if ( !q || jQuery.isArray(data) ) {
q = jQuery. _data( elem, type, jQuery.makeArray(data) );
} else {
q.push( data );
}
}
return q || [];
}
},
デキュー: function( elem, type ) {
type = type || "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, type ".run", フック );
fn.call( elem, function() {
jQuery.dequeue( elem, type );
}, フック );
}
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 ( argument.length < setter ) {
return jQuery.queue( this[0], type ) ;
}
戻りデータ === 未定義 ?
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/
lay: function( time, type ) {
time = jQuery.fx.speeds[ time ] || time : time;
type = "fx"; {
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout(
}); 🎜>clearQueue: function( type ) {
return this.queue( type || "fx", [] );
},
// 特定のタイプのキューが空になったときに解決された Promise を取得します
// (デフォルトでは fx がタイプです)
promise: function( type, object ) {
if ( typeof type !== "string" ) {
object = type;
タイプ = 未定義;
}
type = タイプ || "fx";
var defer = jQuery.Deferred()、
elements = this、
i = elements.length、
count = 1、
deferDataKey = type "defer"、
queueDataKey = type "queue",
markDataKey = type "mark",
tmp;
関数solve() {
if ( !( --count ) ) {
defer.resolveWith( 要素, [ 要素 ] );
}
}
while( i-- ) {
if (( tmp = jQuery.data( elements[ i ], deferDataKey, unknown, true ) ||
( jQuery.data ( elements[ i ]、queueDataKey、unknown、true ) ||
jQuery.data( elements[ i ]、markDataKey、unknown、 true ) ) &&
jQuery.data( elements[ i ]、deferDataKey、jQuery. Callbacks( "1 回のメモリ" ), true ) )) {
count ;
tmp.add(resolve);
}
}
resolve();
return defer.promise( object );
}
});
})( jQuery );


現時点では、実際に jQuery 内でフック機構が普及しています。1.5 は css モジュールの cssHooks、1.6 は属性モジュールの attrHooks、propHooks、boolHooks、nodeHooks、1.7 はイベント モジュールの fixHooks、keyHooks、mouseHooks、 1.8 はモジュールの _queueHooks です。_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) );
queue.push( data );
}
リターンキュー ||
}
},
デキュー: function( elem, type ) {
type = type || 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 = queue .shift();
}
if ( fn ) {
// fx キューが自動的にデキューされないように進行状況監視を追加します
//
if ( type === " fx" ) {
queue.unshift( "inprogress" );
}
// 最後のキューをクリアします stop function
deletehooks.stop;
fn.call( elem, next , フック );
}
if ( !queue.length && フック ) {
hooks.empty.fire();
}
},
// パブリック向けではありません消費 - queueHooks オブジェクトを生成するか、現在のものを返します。 ._data( elem, key, {
empty: jQuery.Callbacks("1 回メモリ").add(function() {
jQuery.removeData( elem, type "queue", true );
jQuery .removeData( elem, key, true );
})
})
}
});
jQuery.fn.extend({
queue: function( type,データ) {
var setter = 2;
if (typeof type !== "string" ) {
type = "fx";
}
if ( argument.length < setter ) {
return jQuery.queue( this[0], type );
}
return data === 未定義 ? :
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/
lay: function( time, type) {
time = jQuery.fx.speeds[ time ] || time : time;
type = "fx" || return this.queue( next, フック ) {
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" ) {
type = 未定義; type = type || "fx";
while( i-- ) {
if ((tmp = jQuery._data( elements[ i ], type "queueHooks" )) && tmp.empty ) {
カウント ;
tmp.empty.add( 解決 );
}
}
return defer.promise( obj )
}) ;


同時に、アニメーション モジュールは 3 回目の大規模な再構築を開始し、フック Tween.propHooks も追加されました。さらに 2 つのオブジェクトがあり、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 = Anime( this, jQuery.extend( {}, prop ), optall ) ;
// 空のアニメーションはすぐに解決されます
if ( empty ) {
}
}; false ?
this.each( doAnimation ) :
this.queue( optall.queue, doAnimation );
},


これまでのところ、すべての非同期処理は次のようになります。 jQuery を非同期キューの「サブクラス」または「バリアント」に変換する方が適切です。 Promise、Delay、またはさまざまな特殊効果メソッドを実行した後の domReady、アニメーション、AJAX、および jQuery オブジェクトなど。したがって、すべての非同期のものは Promise の保護下にあり、非同期プログラムは同期と同じように作成されます。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。