jqueryソースのwhen
$.when()は$です.Deferred()の補助方法.
一、whenの使い方.
whenは複数のDeferredオブジェクトをパラメータとして受け入れ、以下のいくつかのケースがあります.
1.インバウンドまたはインバウンドがいずれもDeferredオブジェクトでない場合、直接$を実行する.when().done()に追加された関数.
2.1個のDeferredオブジェクトがパラメータとして使用する場合、Deferredオブジェクトが成功すると$が実行される.when().done()が追加したイベントは、失敗するとwhenのfailが追加した関数を実行します.
3.複数のDeferredオブジェクトがパラメータとして使用する場合、すべてのDeferredオブジェクトが正常に完了すると$がトリガーされる.when().done()に追加するイベントは、失敗すると$が実行される.when().fail()が追加したイベント.
二、ソースコード解析
(1)whenの中に1つしか入参していない場合
ソースコードの中に、内部のdeferredオブジェクトにパラメータが割り当てられていることを発見しました.このオブジェクトは$です.whenで作成され、返されます.この場合、中間のステップをスキップし、最後までreturn deferredに戻ります.promise()は、参照されたpromiseオブジェクトに戻り、doneイベントとfailイベントを追加します(同じdeferredオブジェクトに複数のdoneまたはfailを追加し、順番に実行できます).deferredオブジェクトのresolveを実行した後、doneに追加した関数を実行します.
(2)複数の入参がある場合、複数の入参がある場合、$.when()の内部には、$をコールバックするためのdeferredオブジェクトが作成されます.when().done().fail()に追加された関数.原理を見てみましょう.
一、whenの使い方.
whenは複数のDeferredオブジェクトをパラメータとして受け入れ、以下のいくつかのケースがあります.
1.インバウンドまたはインバウンドがいずれもDeferredオブジェクトでない場合、直接$を実行する.when().done()に追加された関数.
$.when()
.done(function(){
alert("OK");
})
.fail(function(){
alert("failed") ;
});
var a , b, c;
$.when(a,b,c)
.done(function(){
alert("OK");
})
.fail(function(){
alert("failed") ;
});
2.1個のDeferredオブジェクトがパラメータとして使用する場合、Deferredオブジェクトが成功すると$が実行される.when().done()が追加したイベントは、失敗するとwhenのfailが追加した関数を実行します.
var dfd1= $.Deferred();
dfd1.done(function(){
alert(1);
});
$.when()
.done(function(){
alert("OK");
})
.fail(function(){
alert("failed") ;
});
dfd1.resolve();
3.複数のDeferredオブジェクトがパラメータとして使用する場合、すべてのDeferredオブジェクトが正常に完了すると$がトリガーされる.when().done()に追加するイベントは、失敗すると$が実行される.when().fail()が追加したイベント.
var dfd1= $.Deferred(),
dfd2= $.Deferred();
dfd1.done(function(){
alert(1);
});
dfd2.done(function(){
alert(2);
});
$.when(dfd1,dfd2)
.done(function(){
alert("OK");
})
.fail(function(){
alert("failed");
});
dfd1.resolve();
dfd2.reject();
二、ソースコード解析
(1)whenの中に1つしか入参していない場合
ソースコードの中に、内部のdeferredオブジェクトにパラメータが割り当てられていることを発見しました.このオブジェクトは$です.whenで作成され、返されます.この場合、中間のステップをスキップし、最後までreturn deferredに戻ります.promise()は、参照されたpromiseオブジェクトに戻り、doneイベントとfailイベントを追加します(同じdeferredオブジェクトに複数のdoneまたはfailを追加し、順番に実行できます).deferredオブジェクトのresolveを実行した後、doneに追加した関数を実行します.
(2)複数の入参がある場合、複数の入参がある場合、$.when()の内部には、$をコールバックするためのdeferredオブジェクトが作成されます.when().done().fail()に追加された関数.原理を見てみましょう.
<pre name="code" class="javascript">when: function( subordinate /* , ..., subordinateN */ ) {
var i = 0,
resolveValues = slice.call( arguments ), // arguments
length = resolveValues.length,
// the count of uncompleted subordinates
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,//
// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
deferred = remaining === 1 ? subordinate : jQuery.Deferred(), //Deferred , , ,
if ( length > 1 ) { // when 1 , if progressValues = new Array( length ); progressContexts = new Array( length ); resolveContexts = new Array( length ); for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { //Deferred if resolveValues[ i ].promise() // deferred done fail .done( updateFunc( i, resolveContexts, resolveValues ) ) // updateFunc .fail( deferred.reject ) // fail deferred reject .progress( updateFunc( i, progressContexts, progressValues ) ); } else { --remaining; } } } // If we're not waiting on anything, resolve the master if ( !remaining ) { // remaining0, if deferred.resolveWith( resolveContexts, resolveValues ); } return deferred.promise();
転送されたDeferredオブジェクトは、実行に成功した後、doneイベントのupdateFunc内部で返される匿名関数をコールバックし、その後--remaining、パラメータとしてのDeferredオブジェクトがすべて正常に実行され、remainingが0の場合、deferred.resolve()実行、コールバック$.when().done()が追加したコールバック.実行に失敗した場合、外部パラメータfailイベントがトリガーされ、内部deferredが実行されます.reject()では、$をコールバックする.when().fail()に追加されたコールバックupdateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( values === progressValues ) { deferred.notifyWith( contexts, values ); } else if ( !( --remaining ) ) { deferred.resolveWith( contexts, values ); } }; },