jQuery遅延オブジェクト(詳細な説明)

1月31日に、jQuery 1.5がリリースされました。jQuery1.5の主要な革新の1つは、遅延オブジェクトツールでした。 この記事で詳しく説明したいのは、彼についてです。

ライブラリのこの新しい機能は、ハンドラー(コールバック)の遅延呼び出しによる作業を簡素化することを目的としています。 jQueryと同様に、遅延オブジェクトはチェーン可能ですが、独自のメソッドセットがあります。 今度は多くのハンドラを検出することが可能な繰延オブジェクト、原因キュー・ハンドラに登録し、同期または非同期機能のために、「完了」または「エラー」に状態を切り替えます。

概要


アイデアは非常に単純です:遅延オブジェクトを作成し、このオブジェクトをハンドラーをフックできる(またはフックしない)外部コードに渡し、1つのオブジェクトメソッドを呼び出すだけでこれらのハンドラーの実行を開始する必要があります。

遅延オブジェクトを使用するプロセス全体は、3つのグローバルステージに分割できます。

遅延オブジェクトの説明にある「キュー」という言葉は、理由のために使用されます。キューに追加されたハンドラーは、追加された順に呼び出されます(先に追加された方が先に呼び出されます)。

ハンドラーを追加する場合、遅延オブジェクトの状態(既に実行またはキャンセルされている場合)を確認する必要はまったくありません。 「run」/「error」ハンドラーが既に「run」/「canceled」オブジェクトに追加された場合、すぐに呼び出されます。

遅延オブジェクトで繰り返し解決/拒否の呼び出しを行っても、その状態とハンドラーへのコールバックは変更されませんが、単に無視されます(以前にどの解決()または拒否()が呼び出されたかは関係ありません)。

繰延オブジェクトのメソッド(すべてではない)ことを意味し、«は、連鎖»それらを分離し、行オブジェクトに複数のメソッドを呼び出すことが可能となる元のオブジェクトへの参照を返します。 たとえば、次のようになります。deferred.done(callback1).fail(callback2);

メソッドの説明


deferred.done(doneCallbacks)
遅延オブジェクトが「完了」状態になったときに呼び出されるハンドラーを追加します

deferred.fail(failCallbacks)
遅延オブジェクトが「キャンセル」状態になったときに呼び出されるハンドラーを追加します

deferred.then(doneCallbacks、failCallbacks)
ハンドラは直ちに上記両タイプ、等価レコードdeferred.done(doneCallbacks).fail(failCallbacks)を追加します

上記の3つのメソッドでは、個々の関数または関数の配列がdoneCallbacks、failCallbackの引数として機能できます。

deferred.resolve(引数)
「完了」の状態に遅延オブジェクトを変換し、引数のパラメータを持つすべてのハンドラのdoneCallbacks(通常の転送パラメータのカンマ)を引き起こします

deferred.reject(引数)
遅延オブジェクトを「キャンセル」状態にし、argsパラメーターですべてのfailCallbacksハンドラーを呼び出します

上記の2つのメソッドを使用する場合のハンドラーの呼び出し(関数内)のコンテキストは、遅延オブジェクト(または、投影を作成できない場合はオブジェクト自体)の投影になります(遅延投影とは、deferred.promise()の説明を参照)。 別の呼び出しコンテキストでハンドラー関数を実行する場合は、次の2つのメソッドを使用する必要があります。

deferred.resolveWith(コンテキスト、引数)
deferred.rejectWith(コンテキスト、引数)
方法全く同様.resolve(引数)と.reject(引数)は、唯一のコンテキストは、このキーワードを介してハンドラ関数内の利用できるようになります

メソッドを使用して、遅延オブジェクトの状態を確認できます。

deferred.isResolved()
deferred.isRejected()
メソッドは、オブジェクトの現在の状態に応じてtrueまたはfalseを返します。 ハンドラーが実行されたとき(ただし、最後のハンドラーはまだ実行されていません)、対応するメソッドはtrueを返します。

deferred.promise()を使用して投影を作成する


この方法は、「投影»繰延オブジェクトを作成し、返します - それはハンドラを追加し、状態を確認するためのメソッドを持つオブジェクトのコピーをsvoebraznaya。 つまり 元と同じハンドラーのキューで動作する遅延オブジェクトを取得します。ハンドラーを追加でき、元のオブジェクトの状態を表示できますが、元のオブジェクトの状態を変更することはできません。

投影を作成すると、所定の位置に外部コードハンドラを追加する機能を提供したい時に必要であり、不正な呼び出し方法から保護すると同時に、オブジェクトの状態を変更します。

遅延オブジェクトの作成


遅延オブジェクトを作成するには、2つの方法があります。$ .Deferred()メソッドを使用して新しいネイティブインスタンスを作成する(新しいキーワードはオプションです)か、$ .when(args)メソッドを呼び出して、以前に作成した遅延オブジェクトを使用します。

$ .Deferred(func)

このメソッドは、新しい遅延オブジェクトを返します。 func引数はオプションです。作成されたオブジェクトを初期化する関数を渡してから、コンストラクタから返すことができます。 func関数内では、thisおよび/または最初の関数引数を介して、初期化された遅延オブジェクトにアクセスできます。

$ .when(遅延1、遅延2、...)

このメソッドは、すべての引数(遅延オブジェクト)がこの状態になるか、少なくとも1つの引数が取り消されるとすぐに「キャンセル」状態になると、「実行」状態になる遅延オブジェクトを作成するために使用されます。

すべてのタスクが完了するのを待ってからタスクを完了したい場合は、この場合はこのメソッドを使用します。
例1
$.when($.get( '/echo/html/' ), $.post( '/echo/json/' )).done( function (args1, args2) { alert( " " ); });

このコードは、両方のページが指定されたブロックに正常にロードされた後にのみ、「ロードが完了しました」というメッセージを表示します。

非遅延オブジェクトが$ .when()の引数として検出された場合、このタスクはすでに正常に完了しているとみなされ、メソッドプログラムは残りの引数によってガイドされます。

$ .when()メソッドで受け取った遅延オブジェクトが呼び出しコンテキスト(関数内)により「実行」状態になると、この遅延オブジェクトのプロジェクターが投影され、$で渡された対応する実行引数を含む配列が引数としてハンドラーに渡されます。 .when()遅延オブジェクト(または1つの引数自体(ある場合))。 上記の例では、args1は最初のajaxリクエストに対して成功を呼び出す引数の配列であり、args2は2番目のリクエストに対してです。

$ .ajax()で遅延オブジェクトを使用する


jQuery 1.5では、ajaxエンジンが根本的に書き換えられ、 $ .ajax()メソッドとその短縮バージョンも遅延オブジェクトを使用するようになりました。 これにより、いくつかのハンドラーを要求完了イベントに(成功または誤って)かなり簡単な方法で割り当てることができ、ハンドラーをいくつかの並列要求の完了に割り当てることができます。

メソッド$ .ajax()、$ .get()、$ .post()、$ .getScript()、$ .getJSON()から、遅延オブジェクトの投影を持つオブジェクトが返されます。 キューにハンドラを追加し、このオブジェクトを$ .when()の引数として使用できるメソッドがあります。

このオブジェクトに加えて、メソッドの同義語が追加されます。これは、ajaxリクエストのトピックにより適しています。

興味深い事実


$ .when()メソッドは、遅延オブジェクトに属しているかどうかの引数を評価するときに、.promise()メソッドの存在を確認します。そのようなメソッドが存在する場合、「左」オブジェクトも遅延と見なされます。 このような「左」のオブジェクトにアクセスすると、延期されたかのように実行エラーが発生するため、これにバグが関連付けられています。

jQuery(jquery-git.js)の最新の開発バージョンでは、遅延オブジェクトにも.invert()メソッドがあり、これは.promise()メソッドと同様に、「その逆」メソッドのみでオブジェクトのプロジェクションを作成します:done <=> fail、isResolved < => isRejected、約束<=>反転。 この方法の適用はまだ気づいていません。

使用例


例1.(上記を参照)は、いくつかのAjaxリクエストの完了を追跡するという典型的な問題の解決策をすでに示しています。

例2
// 3
function test() {
var d = $.Deferred();
setTimeout( function () { d.resolve(); }, 3000);
return d.promise();
}

var t = test().done( function () { alert( " " ); });

//
setTimeout( function () {
alert( " " );
t.done( function () { alert( "" ); });
}, 5000);


* This source code was highlighted with Source Code Highlighter .

これは単なるデモの例で、遅延オブジェクトが構築され、その状態は3秒後に「完了」に変換され、外部コードに発行されます。 外部コードでは、1つのハンドラーがすぐに追加されます。状態が既に「完了」している場合、3秒後に呼び出され、5秒後に2番目に呼び出されるため、追加時にすぐに呼び出されます。

例3
< div id ="d1" style ="width:100px;height:100px;background:red;" > 1 </ div >
< div id ="d2" style ="width:100px;height:100px;background:green;" > 2 </ div >


* This source code was highlighted with Source Code Highlighter .

//
var a1 = $.Deferred(),
a2 = $.Deferred();

$( '#d1' ).slideUp(2000, a1.resolve);
$( '#d2' ).fadeOut(4000, a2.resolve);

a1.done( function () { alert( 'a1' ); });
a2.done( function () { alert( 'a2' ); });
$.when(a1, a2).done( function () { alert( 'both' ); });


* This source code was highlighted with Source Code Highlighter .

このコードは、複数のアニメーションを完了した後にコードを実行する必要がある場合の、より現実的な問題の解決策の例を示しています。 1つの要素にアニメーション完了ハンドラーを追加するのは非常に簡単です(これも使用されます)が、独立したアニメーションの完了を追跡するのは多少難しくなります。 オブジェクトの使用及び繰延$ .when()のコードで理解しやすくなります。

すべてのサンプルは、 jsfiddle.netサービスで実行および確認できます。

材料:
blog.jquery.com/2011/01/31/jquery-15-released
api.jquery.com/category/deferred-object
www.erichynds.com/jquery/using-deferreds-in-jquery (翻訳: habrahabr.ru/blogs/jquery/112960
JQuery 1.5のソースコードドキュメント

Source: https://habr.com/ru/post/J113073/


All Articles