jQuery-v2.0.3ソース浅い分析05-when
3287 ワード
jQueryが提供するwhenメソッドは、複数のDeferredオブジェクトを管理できます.たとえば、複数のDeferredオブジェクトを作成した場合、すべてのDeferred呼び出しが完了した後にコードを実行したい場合は、whenを使用して実現できます.
ソースコード
げんり
whenの原理:remainingを利用してDeferredの数を記録し、伝達されたものがDeferredオブジェクトでない場合は記録しない(ソースコードで直接remaining-1操作を行う).Deferredが正常に実行されるとremainingは-1操作され、最後のDeferredが正常に実行されると(remainingが0に等しい場合)whenメソッドで作成されたDeferredオブジェクトがトリガーされます.いずれかのDeferred呼び出しに失敗したメソッドが発生した場合は、whenのrejectを直接呼び出します.入力されたパラメータがDeferredオブジェクトでない場合は、コールバック関数が直接呼び出されます.
説明する
まず、ソース3095行とソース3098行を見てみましょう.ここでは、入力されたパラメータが1つしかなく、Deferredオブジェクトである場合、このDeferredオブジェクトを直接使用し、入力されたパラメータがDeferredオブジェクトでない場合、または複数のパラメータが存在する場合、新しいDeferredオブジェクトを直接作成することを意味します.
ソースコード3116行は、パラメータの個数が1個より大きい場合、まずこれらのパラメータをループしてDeferredオブジェクトかどうかを判断し、そうでなければremainingを直接-1操作し、DeferredオブジェクトであればdoneとprogressがupdateFunc関数を呼び出しているのを見ることができる.3番目のパラメータがprogressValuesであれば、作成したdeferredのnotifyWithを直接呼び出すので、whenの後ろにバインドされたprogressは、パラメータのDeferredオブジェクトに基づいてprogressを呼び出す回数を複数回トリガーする可能性があります.doneがトリガするupdateFuncメソッドの場合、この場合はまずremainingを-1操作し、remainingが0に等しい場合はdeferredのresolveWithを直接トリガします.
ソース3133行は,我々が入力したパラメータがすべてDeferredオブジェクトでなければ,このとき我々が直接成功をトリガする方法を意味する.最後にpromise();ステータスを変更する方法は外部に提供されません.
使用法
ソースコード
/** 3089 **/
when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
resolveValues = core_slice.call( arguments ),
length = resolveValues.length,
/** 3095 **/
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
/** 3098 **/
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
// Update function for both resolve and progress values
updateFunc = function( i, contexts, values ) {
return function( value ) {
contexts[ i ] = this;
values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
if( values === progressValues ) {
deferred.notifyWith( contexts, values );
} else if ( !( --remaining ) ) {
deferred.resolveWith( contexts, values );
}
};
},
progressValues, progressContexts, resolveContexts;
/** 3116 **/
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
resolveContexts = new Array( length );
for ( ; i < length; i++ ) {
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
resolveValues[ i ].promise()
.done( updateFunc( i, resolveContexts, resolveValues ) )
.fail( deferred.reject )
.progress( updateFunc( i, progressContexts, progressValues ) );
} else {
--remaining;
}
}
}
/** 3133 **/
if ( !remaining ) {
deferred.resolveWith( resolveContexts, resolveValues );
}
return deferred.promise();
}
げんり
whenの原理:remainingを利用してDeferredの数を記録し、伝達されたものがDeferredオブジェクトでない場合は記録しない(ソースコードで直接remaining-1操作を行う).Deferredが正常に実行されるとremainingは-1操作され、最後のDeferredが正常に実行されると(remainingが0に等しい場合)whenメソッドで作成されたDeferredオブジェクトがトリガーされます.いずれかのDeferred呼び出しに失敗したメソッドが発生した場合は、whenのrejectを直接呼び出します.入力されたパラメータがDeferredオブジェクトでない場合は、コールバック関数が直接呼び出されます.
説明する
まず、ソース3095行とソース3098行を見てみましょう.ここでは、入力されたパラメータが1つしかなく、Deferredオブジェクトである場合、このDeferredオブジェクトを直接使用し、入力されたパラメータがDeferredオブジェクトでない場合、または複数のパラメータが存在する場合、新しいDeferredオブジェクトを直接作成することを意味します.
ソースコード3116行は、パラメータの個数が1個より大きい場合、まずこれらのパラメータをループしてDeferredオブジェクトかどうかを判断し、そうでなければremainingを直接-1操作し、DeferredオブジェクトであればdoneとprogressがupdateFunc関数を呼び出しているのを見ることができる.3番目のパラメータがprogressValuesであれば、作成したdeferredのnotifyWithを直接呼び出すので、whenの後ろにバインドされたprogressは、パラメータのDeferredオブジェクトに基づいてprogressを呼び出す回数を複数回トリガーする可能性があります.doneがトリガするupdateFuncメソッドの場合、この場合はまずremainingを-1操作し、remainingが0に等しい場合はdeferredのresolveWithを直接トリガします.
ソース3133行は,我々が入力したパラメータがすべてDeferredオブジェクトでなければ,このとき我々が直接成功をトリガする方法を意味する.最後にpromise();ステータスを変更する方法は外部に提供されません.
使用法
var def1 = $.Deferred();
setTimeout(function(){
def1.resolve();
}, 1000);
$.when(def1).done(function(){
console.log(' ');
}).fail(function(){
console.log(' ');
})
//1