ホームページ  >  記事  >  ウェブフロントエンド  >  jQuery 1.5 で遅延オブジェクトを使用するためのコード (翻訳)_jquery

jQuery 1.5 で遅延オブジェクトを使用するためのコード (翻訳)_jquery

WBOY
WBOYオリジナル
2016-05-16 18:09:371166ブラウズ

翻訳者注:
1. Deferred は、多くの人が「非同期キュー」と訳します。結局「遅延」とは関係ないので、「遅延」のほうが信頼性が高いと思いますが、この記事ではまだ遅延という言葉を使用しています。

2. この記事は jQuery1.5 リリース ブログで言及されており、deferred を紹介する最も古典的で詳細な記事でもあります。現在、中国語の資料が比較的少ないという事実を考慮して、皆さんの学習と参考のために特別に翻訳されています。

3. 記事全体は意訳を採用しておりますので、不適切な点がございましたらお気軽にご指摘ください。

jQuery1.5 で新たに追加された Deferreds オブジェクトは、タスク完了の処理メソッドをタスク自体から切り離すことができます。 Mochikit と Dojo という 2 つの JS フレームワークが長い間この機能を実装しているため、これは JavaScript コミュニティでは新しいことではありません。しかし、Julian Aubourg が jQuery 1.5 で AJAX モジュールを書き換えたことにより、遅延は自然に内部実装ロジックになりました。 deferreds オブジェクトを使用すると、タスクの完了時、またはタスクの完了後でも、複数のコールバック関数が実行されるようにバインドできます。これらのタスクは非同期または同期にすることができます。

さらに重要なのは、deferred が $.ajax() の内部実装として実装されているため、AJAX を呼び出すときに deferred によってもたらされるトラバーサルを自動的に取得できることです。たとえば、次のようにコールバック関数をバインドできます:

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

// $ .get、非同期 AJAX リクエスト
var req = $.get('foo.htm').success(function (response) {
// 成功後の AJAX 処理関数
}).error( function () {
// AJAX 失敗後処理関数
}); この関数は、AJAX が終了する前に
doSomethingAwesome() を呼び出す可能性があります。別の AJAX コールバック関数を追加します。AJAX はこの時点で終了しているか、まだ終了していない可能性があります。
// $.ajax には遅延サポートが組み込まれているため、次のように記述できます
req.success(function) (応答) {
/ / この関数は、AJAX が終了した後、または AJAX が終了した場合はすぐに呼び出されます
});


成功は 1 つだけという制限はなくなりました。失敗または完了のコールバック関数。代わりに、いつでも追加されるコールバック関数は先入れ先出しキューに配置されます。
上記の例からわかるように、AJAX リクエストが終了した後でも、コールバック関数を AJAX リクエスト (監視可能なタスク) にアタッチできます。コードの構成は非常に優れており、長いコールバック関数を記述する必要がなくなりました。 $.queue() と pub/sub (通常、イベントベースのモデルで使用されるパブリッシュ/サブスクライブ メカニズム) が融合したようなものです。
さらに深く考えて、いくつかの同時 AJAX リクエストがすべて終了した後、次のようなシナリオを想像してください。 。これは、jQuery の関数 $.when() を使用して簡単に実現できます。


function doAjax() {
return $.get('foo.htm');
}

function doMoreAjax() {
return $.get('bar .htm');
}

$.when(doAjax(), doMoreAjax()).then(function () {
console.log('両方の ajax リクエストが完了すると起動します! ');
}).fail(function () {
console.log('1 つ以上のリクエストが失敗した場合に起動します。');


jsFiddle でサンプルを開きます

各 jQuery AJAX メソッドの戻り値には、非同期リクエストを追跡するための Promise 関数が含まれているため、上記の例は適切に動作します。 Promise 関数の戻り値は、遅延オブジェクトの読み取り専用ビューです。 (Promise は、タスクの結果に対する読み取り専用のビューです。) 遅延関数は、オブジェクト内に Promise() 関数が存在するかどうかを検出することによって、現在のオブジェクトが監視可能かどうかを判断します。 $.when() は、すべての AJAX リクエストが終了するのを待ってから、.then()、.fail() を通じて登録されたコールバック関数を呼び出します (呼び出される特定のコールバック関数は、タスクの終了ステータスによって異なります)。これらのコールバック関数は、登録された順序で実行されます。

さらに良いことに、$.when() は関数または関数の配列をパラメーターとして受け入れます (翻訳者注: これは完全に正しくありません。$.when は 1 つ以上の遅延オブジェクト、またはネイティブ JS オブジェクトを受け入れます。関数配列はパラメーターとして使用できないため)、これらの非同期タスクを自由に組み合わせることができます。

$.ajax() は、promise()、then()、success()、error() 。ただし、元の遅延オブジェクトを操作することはできません。操作できるのは、promise() 関数 (翻訳者注: 先ほどの Promise は読み取り専用ビューであることに注意してください)、および遅延ステータスを検出できる isRejected() および isResolved() 関数のみです。

しかし、なぜ遅延オブジェクトを返さないのでしょうか?完全な遅延オブジェクトが返された場合、より詳細な制御が可能になり、その遅延オブジェクトを自由にトリガーできる可能性があります (翻訳者注: 私は、resolve をトリガーと訳しました。これは、遅延オブジェクトに登録されているすべてのコールバック関数をトリガーすることです) 遅延オブジェクト、したがって、AJAX リクエストが終了する前にすべてのコールバック関数が実行されます。 したがって、パラダイム全体を壊す可能性を避けるために、dfd.promise().promise() のみを返します。) (翻訳者注: の正確な意味について混乱している場合は、上の段落では問題ありませんが、後で詳しく理由を分析する記事を書きますコールバック関数の登録 (コールバックの登録) 上記の例では、then()、success()、fail を使用しています。 () メソッドを使用してコールバック関数を登録します。実際には、特に AJAX リクエストを処理する場合に使用できるメソッドは、すべての遅延オブジェクトで使用できる 関数です。 .when または手動で作成された遅延オブジェクト):



コードをコピー コードは次のとおりです: .then( doneCallbacks, failedCallbacks )
.done(nedCallbacks )
.fail(failCallbacks )


AJAX オブジェクトには 3 つの追加メソッドが含まれており、そのうちの 2 つは前述のメソッドにマップされます。これらのメソッドは主に前のコードとの互換性を目的としています:


コードをコピーします コードは次のとおりです: // "success" と "error" はそれぞれ "done" メソッドと "fail" メソッドにマッピングされます
. success(nedCallbacks )
.error(failCallbacks )


リクエストが成功したか失敗したかに関係なく、リクエストの完了後に呼び出される完全なコールバック関数を登録することもできます。成功関数またはエラー関数、および完全な関数は、実際には別の関数のエイリアスです。 $.ajax() 内で作成されたこの遅延オブジェクトは、AJAX の終了後にコールバック関数 (解決) をトリガーします。

コードは次のとおりです。 :

コードをコピー

コードは次のとおりです:
$.get("/foo/").done( fn ); // 同等: $.get("/ foo /").success( fn ); // 以下と同等: $.get("/foo/", fn );

独自の Deferred の作成
$.ajax と $.when が内部的に遅延インターフェイスを実装していることはわかっていますが、手動で遅延オブジェクトを作成することもできます:
コードをコピーします コードは次のとおりです。

function getData() {
return $.get('/foo/');
}
関数 showDiv() {
var dfd = $.Deferred();
$('#foo').fadeIn(1000, dfd.resolve);
return dfd.
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('アニメーションと AJAX リクエストの両方が完了しました!' ; > jsFiddle の例



showDiv() では、遅延オブジェクトを作成し、アニメーションを実行してから、Promise を返します。この遅延オブジェクトは、fadeIn() の終了後にトリガー (解決) されます。この Promise が返されてから遅延オブジェクトがトリガーされるまでの間に (注意: ここでの遅延とは、showDiv() によって返されたオブジェクトではなく、$.when によって作成されたオブジェクトを指します)、then() コールバック関数が登録されます。このコールバック関数は、両方の非同期タスクが完了した後に実行されます。 getData() は、promise メソッドを持つオブジェクト (翻訳者注: 実際には jQuery によってカプセル化された XMLHttpRequest オブジェクトです) を返します。これにより、$.when() がこの AJAX リクエストの終了を監視できるようになります。 showDiv() で Promise を返すために行った手動の手順は、$.ajax() と $.when() によって内部的に処理されます。2011 年 1 月 15 日: Julian が上記の構文をコメントで指摘しました。 $.Deferred(fn).promise() に縮小されました。したがって、両端の次のコードは同等です: コードをコピーします


コードは次のとおりです:
function showDiv() {
return $.Deferred(function (dfd) {
$('#foo').fadeIn(1000, dfd. solve);
}).promise();
}


カスタム遅延オブジェクトのコールバック関数を追加します (遅延オブジェクトを遅延させます)
さらに一歩進んで getData を提供できます() と showDiv() は、$.then() にコールバック関数を登録するのと同じように、コールバック関数を個別に登録します。 (翻訳者注: 以下の段落は繰り返しで同じ意味なので翻訳しません。コードを見てみましょう)




コードをコピー


コードは次のとおりです。
return $.Deferred(function (dfd) {
// 翻訳者の注: この段落のコードは原文にはありませんが、jsFiddle に表示されます。
// これは、カスタム遅延関数
dfd.done( のコールバック関数を登録するという作成者の本来の意図だと思います) function () {
console.log('アニメーションが成功した後に起動します')
$('#foo').fadeIn(1000, dfd.resolve); ).promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('showDiv() と AJAX の両方の後に起動しますrequest success!');
// 'ajaxResult' はサーバーによって返された結果です
});





jsFiddle で例を開きます




チェーンホットネス
Deferred のコールバック関数は、関数が遅延オブジェクトを返す限り、チェーン内で呼び出すことができます (翻訳者注: dfd.promise( ) は読み取り専用の遅延オブジェクトを返します )。これは実際のコードです (@ajpiano 経由!) コードをコピーします コードは次のとおりです:

function saveContact(row) {
var form = $.tmpl(templates["contact-form"]),
valid = true,
messages = [],
dfd = $.Deferred();
/*
* クライアント検証コードは次のとおりです
*/
if (!valid) {
dfd.resolve({
success: false,
エラー: メッセージ
});
} else {
form.ajaxSubmit({
dataType: "json",
成功: dfd.resolve,
エラー: dfd.reject
});
}
return dfd.promise();
saveContact(row).then(function (応答) {
if (応答) .success) {
// クライアントの検証に合格し、データは正常に保存されました
} else {
// クライアントの検証に失敗しました
// エラー メッセージを出力します
}
}) .fail (function (err) {
// AJAX リクエストが失敗しました
});

saveContact() 関数は、まずフォーム データの有効性を検証し、次に有効性ステータスを保存します。変数は有効です。検証が失敗した場合、直接遅延がトリガーされます (成功ステータス コードとエラー情報を含む JS オブジェクトをパラメーターとしてコールバック関数に渡します)。検証に合格すると、データがサーバーに送信され、AJAX が正常に完了した後に遅延オブジェクトがトリガーされます。 failed() は、AJAX リクエストの正常な完了を妨げる可能性がある 404、500 などの HTTP ステータス コードを処理します。
観察不可能なタスク
遅延は、非同期タスクか同期タスクかに関係なく、タスクとタスク処理関数を分離するのに非常に役立ちます。タスクは Promise を返す場合もありますが、文字列、オブジェクト、またはその他の型を返す場合もあります。
この例では、「アプリケーションの起動」リンクが初めてクリックされると、AJAX リクエストがサーバーに送信され、現在のタイムスタンプが返されます。このタイムスタンプはリンクのデータ キャッシュに保存されます。リンクが再度クリックされると、AJAX リクエストを行わずにタイムスタンプがキャッシュから取得されて返されます。

コードをコピーします コードは次のとおりです。
function startTask(element) {
var timestamp = $.data(element, 'timestamp');
if (timestamp) {
return timestamp;
return $.get('/start-task/') .success( function (timestamp) {
$.data(element, 'timestamp', timestamp);
});
}
}
$('#launchApplication').bind ('click ', function (event) {
event.preventDefault();
$.when(startTask(this)).done(function (timestamp) {
$('#status'). html('

最初にこのタスクを開始した日: 'タイムスタンプ '

')
loadApplication()


$.when() は、最初のパラメーターに Promise 関数がない (したがって監視できない) ことを検出すると、新しい遅延オブジェクトを作成し、遅延オブジェクトをトリガーして、Promise 読み取り専用オブジェクトを返します。したがって、監視できないタスクも $.when() に渡すことができます。
注意すべき点は、オブジェクト自体に Promise 関数がある場合、このオブジェクトを遅延オブジェクトとして使用できないことです。 jQuery は、オブジェクトに Promise 関数があるかどうかをチェックすることで、オブジェクトが延期されているかどうかを判断しますが、Promise が実際に使用可能なオブジェクトを返すかどうかはチェックしません。したがって、次のコードはエラーになります:



コードをコピー
コードは次のとおりです: var obj = { promise: function () {
// 何かをする
}
};
$.when(obj).then(fn); >結論 (結論)
Deferred は、非同期タスクを処理する新しい堅牢な方法を提案します。コードをコールバック関数に編成する従来の方法とは異なり、新しい遅延オブジェクトを使用すると、いつでも (タスク終了後でも) 複数のコールバック関数をバインドでき、これらのコールバック関数は先入れ先出しで呼び出されます。やり方。この記事の情報は理解しにくいかもしれませんが、遅延オブジェクトの使用をマスターすると、非同期で実行されるコードを編成するのが非常に簡単になることがわかります。
この記事は Sansheng Shishang によって書かれ、最初に Blog Park によって公開されたものです。


転載する場合は出典を明記してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。