コードは次のとおりです:
// 本格的な遅延 (2 つのコールバック リスト)
// 完全な非同期キューを作成します (2 つのコールバック関数配列を含む)
// 非同期キューには 3 つの状態があります: 初期化 (未解決) 、成功 (解決)、失敗 (拒否)。
// どのコールバック関数が実行されるかは状態によって異なります。
// ステータスが解決済みまたは拒否に変更された後も、ステータスは変更されません。
Deferred: function( func ) {
// _Deferred には成功または失敗のステータスがありません。初期化、実行、実行完了、キャンセルの 4 つの状態があります。
// コードの再利用のために、最初に _Deferred を実装しました。
// クロージャを通じて参照されるfailDeferred
var deferred = jQuery._Deferred(),
failDeferred = jQuery._Deferred(),
promise
// errorDeferredメソッドを追加し、次にpromise
jQuery.extend( deferred, {
// 成功コールバック関数と失敗コールバック関数をそれぞれのキューに追加します
// 便利なメソッド。2 つのパラメータは配列または null にすることができます
// をすぐに呼び出しますステータスが成功 (解決) の場合は成功コールバック関数
// ステータスが失敗 (拒否) の場合は失敗コールバック関数をすぐに呼び出します。
then: function( donedCallbacks, failedCallbacks ) {
/ /ここでコンテキスト スイッチを指定します。done は deferred を返しますが、fail が実行されると、コンテキストはfailDeferred に変わります。
// 簡単に言うと、
// 呼び出し時に deferred にコールバックを追加します。 done Function donedCallbacks
// 呼び出し時にコールバック関数をfailDeferredに追加しますfailCallbacks
// したがって、この式の行が実行された後、failDeferred
deferred.done( doneCallbacks ).fail(failCallbacks ); 🎜>// 強制復帰遅延
return this;
},
// 解決されるか拒否されるかに関係なく呼び出されるコールバック関数を登録します。
// 実際には、渡された関数 (配列) は deferred とfailDeferred に同時に追加されます
// 想像していたように別の関数配列には格納されません
always: function( ) {
// 完了のコンテキストは遅延に設定され、失敗のコンテキストはこの
// 完了と失敗のコンテキストは矛盾していますか?一貫性のある!ここでは、これは deferred
// に等しいですが、このように設定されたコンテキストをどのように解釈すればよいでしょうか?当時の実装とどう違うのですか?
// 失敗は失敗を指し、failDeferred.done に失敗します。デフォルトのコンテキストは、failDeferred です。failDeferred のコールバック関数配列のコールバックは、クロージャを介して参照されます。
// これを、failDeferred.done の最後にある deferred に置き換えてチェーン呼び出しを実装します。
// つまり、このコンテキストは途中で失われません。
// 文法的には、always によって達成される効果は then によって達成される効果と一致します。
// したがって、これはコード行は 2 行に書き換えることができます ( then の実装と同様)。
// deferred.done( argument ).fail( argument );
// returnr this; >return deferred.done.apply( deferred, argument ).fail. apply( this, argument );
},
// 失敗コールバック関数を追加
// ステータスが失敗した場合にすぐに呼び出されます (拒否されました) )
fail:failDeferred.done,
// 指定されたコンテキストとパラメーターを使用して、失敗コールバック関数を実行します queue
// failedDeferred.rejectWith() を呼び出すことで
rejectWith:failDeferred.resolveWith,
// 失敗コールバック関数キューが呼び出されます
//failDeferred .resolve() を呼び出すことで、
reject:failDeferred.resolve,
// ステータスが成功 (解決済み) かどうかを判断します
isRejected :failDeferred.isResolved,
// 渡されたコールバック関数を毎回呼び出します 成功フィルター関数または失敗フィルター関数を入力し、フィルター関数の戻り値をコールバック関数のパラメーターとして使用します
// 最後に return読み取り専用ビュー (Promise を呼び出して実装する)
// fnDone が成功のステータスにあるかどうか (解決されたときに呼び出されます)
// fnFail はステータスが拒否された (拒否された) ときに呼び出されます
/ / その他の説明について:
// 1. 一部の記事では「パイプライン機構」と訳されていますが、文字通りの意味は理解できないため、少なくとも不正確です
// 2. 誤った理解: いわゆるパイプは、受信した fnDone と fnFail を成功キューと失敗キューの配列の先頭に置くだけです
pipe : function( fnDone, fnFail ) {
return jQuery.Deferred(function( newDefer ) {
jQuery.each( {
done: [ fnDone, "resolve" ], // done はテキストの後半でそれを指します deferred.done
fail: [ fnFail, "reject" ]
}, function ( handler, data ) {
var fn = data[ 0 ],
action = data[ 1 ],
returned;
if ( jQuery.isFunction( fn ) ) {
deferred[ハンドラー ](function() {
returned = fn.apply( this, argument );
if (returned && jQuery .isFunction(returned.promise ) ) {
returned.promise().then( newDefer .resolve, newDefer.reject );
} else {
newDefer[ アクション ]( 返された );
} else {
deferred[ ハンドラー ]( newDefer [ action ] );
}
});
}).promise();
} ,
// obj が提供されている場合、promise アスペクトがオブジェクトに追加されます。
// 返されるのは、resolve と拒否のない不完全な Deferred インターフェイスです。つまり、Deferred オブジェクトの状態は変更できません。
// これは、外部関数が早期にコールバック関数をトリガーするのを防ぐため、読み取り専用ビューと見なすことができます。
//
// たとえば、$.ajax はバージョン 1.5 以降、XMLHttpRequest を返さなくなりましたが、XMLHttpRequest および Deferred オブジェクト インターフェイスをカプセル化したオブジェクトを返します。
// Deferred 部分は、promise() によって取得されます。これにより、外部関数が release および拒否を呼び出すことがなくなり、ajax が完了する前にコールバック関数がトリガーされることがなくなります。
// これら 2 つの関数の呼び出し権限を内部的に ajax に予約します。
promise: function( obj ) {
if ( obj == null ) {
// Promise は実際には 1 回だけ実行され、最初の実行結果は Promise 変数
に格納されます。 if (promise ) {
return Promise;
}
promise = obj = {};
}
var i = PromiseMethods.length>// < をループする別の方法🎜 >// 私は次の使用に慣れています:
// for( i = 0; i < len; i ) または for( i = len-1; i >=0; i-- ) または for( i = len ; i--; )
// jQuery は本当に宝物です。
while( i-- ) {
obj[promiseMethods[i] ] = deferred[promiseMethods[i] ]
}
return
}
}); 🎜>// コールバック リストが 1 つだけ使用されることを確認してください
// 成功したキューの実行が完了した後、失敗したキューのキャンセル メソッドが実行されます
// 失敗したキューの実行が完了した後、成功したキューはcancel メソッドが実行されます
// 関数キューが 1 つだけ実行されることを確認します。つまり、実行成功キューまたは実行失敗キューのいずれかです。
// つまり、ステータスは成功または実行のいずれかのみです。失敗、クロスコールなし
// deferred およびfailDeferredのcancel属性はクロージャを通じてのみ参照できるため、状態とコンテキストの混同を心配する必要はありません
deferred.done(failDeferred.cancel).fail( deferred.cancel );
// unexpose cancel
// キャンセル インターフェイスを非表示にします。つまり、成功した関数キューを外部からキャンセルできません。
deferred.cancel
// 指定された呼び出しfunc if any
// 受信 func 関数を実行します
if ( func ) {
func.call( deferred, deferred );
}
return deferred;
5.5 jQuery.when
コードをコピー
コードは次のとおりです: // 遅延ヘルパー // 非同期キュー ツール関数// firstParam: 1 つまたは複数の遅延オブジェクトまたは JavaScript の通常のオブジェクト
when: function( firstParam ) { var args = argument,
i = 0,
length = args.length,
count = length,
// argument.length が 1 に等しく、firstParam が Deferred の場合、deferred=firstParam
// それ以外の場合、新しい Deferred オブジェクトを作成します (arguments.length が 0 または 1 より大きい場合、新しい Deferred オブジェクトを作成します)
// jQuery.isFunction( firstParam.promise ) を通じて Deferred オブジェクトかどうかを単純に判断します
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
firstParam :
jQuery.Deferred()
// 成功した (解決する) コールバック関数を構築します
functionsolveFunc( i ) {
return function( value ) {
// 渡されたパラメーターが 1 より大きい場合、受け取ったパラメーターを実数の配列に変換します (引数にはスライス メソッドがないため、借用します)卵を産む鶏)
args[ i ] = argument.length > sliceDeferred.call( argument, 0 ) : value; / FF4 の奇妙なバグ:
// 引数オブジェクトに変更された値が、$.when メソッドの外で未定義の値になる場合があります。オブジェクトを新しい配列にクローンすると、問題が解決されます。 🎜>// コールバック関数キューが正常に実行され、コンテキストは
deferred.resolveWith( deferred, slideDeferred.call( args, 0 ) ) );
に渡された最初の Deferred オブジェクトに強制されます。 🎜>}
// パラメータが複数ある場合
if ( length > 1 ) {
for( ; i // 単純に、 Deferred オブジェクトの場合、 .promise().then() を呼び出します。それ以外の場合は、
if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
// 成功コールバックを追加します。関数と失敗コールバック関数をそれぞれのキューに送信します
args[ i ].promise().then(solveFunc(i), deferred.reject );
} else {
// であることを示すカウンターこれは Deferred オブジェクトではなく、通常の JavaScript オブジェクトであることがわかりました。
--count;
}
}
// カウンタが 0 の場合、渡されたパラメータがどれも存在しないことを意味します。 Deferred オブジェクト
// 実行成功のコールバック関数のキュー。コンテキストは、
if ( !count ) {
deferred.resolveWith( deferred, args ); で渡される最初の Deferred オブジェクトになります。
// deferred !== firstParam、つまり deferred は新しく作成された Deferred オブジェクトです
// つまり、length == 0
} else if ( deferred !== firstParam ) {
// 正常に実行された場合のコールバック関数のキュー。コンテキストは新しく作成された Deferred オブジェクトに強制されます。
deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
// 最初のオブジェクトを返します。渡された Deferred、または新しく作成された Deferred オブジェクトの読み取り専用ビュー
return deferred.promise();
}
l jQuery。 ajax()
n TODO
5.7 学習できるスキル
l クロージャ
コードをコピー
コードは次のとおりです:
function a(){
var guid = 1;
return function(){
return guid ;
var defer = a();