jQuery 1.5でdeferredオブジェクトのコードを使用(翻訳)
10151 ワード
注:1.DeferredはjQuery 1です.5新しい特性は、多くの人がそれを「非同期キュー」に翻訳しているので、頼りになると思います.結局、「遅延」とは関係ありませんが、この文章ではdeferredという単語を採用しています.
2.この文章はjQuery 1にあります.5のブログでは、deferredの比較的古典的で深い文章を紹介しています.現在の中国語の資料が少ないことを考慮して、特に翻訳してみんなの学習の参考に供します.
[原句]全編意訳の方式を採用していますが、もし不適切があれば、皆さんに提出してください.
jQuery1.5に追加されたDeferredsオブジェクトは、タスクが完了した処理をタスク自体とデカップリングすることができます.これはJavaScriptコミュニティでは新しい意味はありません.MochikitとDojoの2つのJSフレームワークが長い間この特性を実現していたからです.しかしJulian Aubourg対jQuery 1.5におけるAJAXモジュールの書き換えは,deferredsが当然内部の実装ロジックとなっている.deferredsオブジェクトを使用すると、複数のコールバック関数をタスク完了時にバインドしたり、タスク完了後にバインドしたりすることができます.これらのタスクは非同期であっても同期であってもよい.
さらに重要なのは、deferredsが$として機能していることです.ajax()の内部実装なので、AJAXを呼び出すときにdeferredsがもたらす遍歴を自動的に取得できます.たとえば、コールバック関数をバインドできます.
成功、失敗、または完了したコールバック関数が1つしかないことに制限されません.逆に、これらの随時追加されるコールバック関数は、先進的な先頭キューに配置されます.
上記の例から分かるように、コールバック関数は、AJAX要求(任意の観察可能なタスクobservable task)に付加され、AJAX要求が終了した場合でもよい.コードの組織には良いので、長いコールバック関数を書く必要はありません.これは$のようです.queue()はpub/sub(イベント処理に基づくモデルで一般的に使用されるサブスクリプションメカニズムのパブリッシュ)に遭遇する.
さらに深く、いくつかの同時AJAXリクエストがすべて終了した後にコールバック関数を実行するシーンを想像します.私はjQueryの関数$を簡単に通過することができます.when()で完了します.
jsFiddleでサンプルを開く
上記の例は正常に動作します.これは、各jQueryのAJAXメソッドの戻り値に、非同期要求を追跡するためのpromise関数が含まれているためです.Promise関数の戻り値はdeferredオブジェクトの読み取り専用ビューです.(The promise is a read-only view into the result of the task.)Deferredsは、オブジェクトにpromise()関数が存在するか否かを検出することにより、現在のオブジェクトが観察可能か否かを判断する.$when()は、すべてのAJAXリクエストが終了するのを待って呼び出します.then(), .fail()に登録されたコールバック関数(タスクの終了状態に応じて呼び出されるコールバック関数).これらのコールバック関数は、登録順に実行されます.
もっと良いのは、$.when()は、関数または関数の配列をパラメータとして受け入れます.$.whenは、1つ以上のdeferredオブジェクト、またはオリジナルのJSオブジェクトを受け入れます.関数の配列をパラメータとしてはいけません.これにより、これらの非同期タスクを任意に組み合わせることができます.
$.ajax()は、promise()、then()、success()、error()などのdeferred関数を関連付けたオブジェクトを返します.しかし、元のdeferredオブジェクトを操作することはできません.promise()関数(訳者注:さっき述べたpromiseは読み取り専用ビューであることを覚えています)と、deferred状態を検出できるisRejected()とisResolved()関数だけです.
しかし、なぜdeferredオブジェクトを返さないのですか?完全なdeferredオブジェクトを返すと、より多くの制御があり、任意にトリガーできるかもしれません(訳者注:resolveをトリガーに翻訳すると、deferredオブジェクトに登録されているすべてのコールバック関数がトリガーされます)deferredオブジェクトがトリガーされ、AJAXリクエストが終了する前にすべてのコールバック関数が実行されます.したがって、deferredをトリガするリスクを回避するために、dfdのみを返すべきである.promise().(Therefore, to avoid potentially breaking the whole paradigm, only return the dfd.promise().)(注:もしあなたが上のいくつかの言叶の正确な意味を迷っているならば、大丈夫です.私は后で1篇の文章を书いて深层的にその中の原因を分析してコールバック関数(Registering Callbacks)の上の例を登录して、私达はthen()、success()、fail()方法を使ってコールバック関数を登录して、実は更に多くの方法が使うことができて、特にAJAXの要求を処理する时.具体的にどのような方法を使うかは、結果の状態に対する関心にかかっています.すべてのdeferredオブジェクトにある関数(AJAX,$.whenまたは手動で作成されたdeferredオブジェクト):
AJAXオブジェクトには3つの追加のメソッドが含まれています.このうち2つは前述のメソッドにマッピングされます.これらの方法は主に以前のコードと互換性を持つためです.
completeのコールバック関数を登録することもできます.このリクエストが成功したか失敗したかにかかわらず、リクエストが終了した後に呼び出されます.successやerror関数とは異なり、complete関数は実際にはdeferredオブジェクトのdone関数別名です.これは$です.ajax()内部に作成されたdeferredオブジェクトは、AJAXの終了後にコールバック関数(resolve)をトリガーします.
したがって、次の3つの例は等価です(AJAXのコンテキストでは、successはdone関数よりも楽に見えますよね?)(注:実は私たちが以前のAJAX呼び出し方式を熟知しているため、先入観を主としているだけで、あるいは思考の定勢と呼ばれています):
独自のdeferredオブジェクトを作成する
私たちは$を知っています.ajaxと$.whenは内部でdeferredインタフェースを実装していますが、deferredオブジェクトを手動で作成することもできます.
jsFiddleでサンプルを開く
showDiv()では、deferredオブジェクトを作成し、アニメーションを実行してpromiseに戻ります.このdeferredオブジェクトはfadeIn()の終了後にトリガーされます.このpromise戻りとdeferredオブジェクト(注:ここでのdeferredはshowDiv()戻りのオブジェクトではなく$.whenが作成したオブジェクトを指す)がトリガーされる間に、then()コールバック関数が登録されます.このコールバック関数は、2つの非同期タスクがすべて終了した後に実行されます.
getData()は、jQueryパッケージのXMLhttpRequestオブジェクトがpromiseメソッドを持つオブジェクトを返し、$を許可する.when()は今回のAJAXリクエストの終了を監視しています.The manually steps we took to return a promise in showDiv() is handled for us internally by $.ajax() and $.when().
1/15/2011:Julianはコメントの中で、上の文法は$に簡略化することができると指摘した.Deferred(fn).promise().したがって、次の両端コードは等価です.
カスタムdeferredオブジェクトにコールバック関数(Defer your Deferreds)を追加
さらに、$のようにgetData()とshowDiv()にコールバック関数をそれぞれ登録することができます.then()にコールバック関数を登録するのと同じです.(訳者注:次の段落の内容は繰り返して、すべて1つの意味を言って、翻訳しないで、コードを見ましょう)
jsFiddleでサンプルを開く
チェーンコード
Deferredのコールバック関数は、deferredオブジェクトが返される限り、チェーンで呼び出すことができます(訳者注:dfd.promise()は読み取り専用のdeferredオブジェクトを返します).これは実際のコードです(via@ajpiano!)
saveContact()関数は、まずフォームデータの有効性を検証し、変数validに有効性状態を保存します.検証に失敗すると、直接deferredがトリガーされます(successステータスコードとエラーメッセージを含むJSオブジェクトをパラメータとしてコールバック関数に渡します).検証に合格した場合、サーバにデータを送信し、AJAXが正常に完了した後にdeferredオブジェクトをトリガーします.fail()は、AJAXリクエストが正常に完了したHTTPステータスコードを404500など処理します.
観察不可能なタスク(Non-observable Tasks)
Deferredsは、非同期タスクや同期タスクにかかわらず、タスクとタスクの処理関数をデカップリングする場合に便利です.1つのタスクはpromiseを返すかもしれませんが、文字列、オブジェクト、または他のタイプを返すこともできます.
この例では、「Lanch Application」リンクが最初にクリックされると、AJAXリクエストがサーバに送信され、現在のタイムスタンプに戻ります.その後、このタイムスタンプはこのリンクのdataキャッシュに保存されます.このリンクが再びクリックされると、AJAXリクエストを発行せずにキャッシュからこのタイムスタンプを取り出して返すだけです.
$になるwhen()は、最初のパラメータにpromise関数がないことを発見し(したがって観察できません)、新しいdeferredオブジェクトを作成し、deferredオブジェクトをトリガーし、promise読み取り専用オブジェクトに戻ります.したがって、任意の観察不可能なタスクも$に伝達することができる.when()の中.
1つの問題は、オブジェクト自体がpromise関数を持っている場合、このオブジェクトはdeferredオブジェクトとして使用できないことです.jQueryは、オブジェクトがdeferredであるかどうかを判断し、promise関数があるかどうかを確認することによって決定しますが、jQueryはこのpromiseが本当に利用可能なオブジェクトを返すかどうかをチェックしません.次のコードでエラーが発生します.
結論(Conclusion)
Deferredsは、非同期タスクを処理するための新しい堅牢な方法を提案した.従来のコールバック関数にコードを整理するのとは異なり、新しいdeferredオブジェクトでは、タスクの終了後でもいつでも複数のコールバック関数をバインドできますが、これらのコールバック関数は先進的に呼び出されます.この文章の情報は消化しにくいかもしれませんが、deferredオブジェクトの使用を把握すると、組織が非同期で実行するコードが非常に簡単であることがわかります.
この文章は三生石上オリジナル、ブログ園から先発して、転載して出典を明記してください
2.この文章はjQuery 1にあります.5のブログでは、deferredの比較的古典的で深い文章を紹介しています.現在の中国語の資料が少ないことを考慮して、特に翻訳してみんなの学習の参考に供します.
[原句]全編意訳の方式を採用していますが、もし不適切があれば、皆さんに提出してください.
jQuery1.5に追加されたDeferredsオブジェクトは、タスクが完了した処理をタスク自体とデカップリングすることができます.これはJavaScriptコミュニティでは新しい意味はありません.MochikitとDojoの2つのJSフレームワークが長い間この特性を実現していたからです.しかしJulian Aubourg対jQuery 1.5におけるAJAXモジュールの書き換えは,deferredsが当然内部の実装ロジックとなっている.deferredsオブジェクトを使用すると、複数のコールバック関数をタスク完了時にバインドしたり、タスク完了後にバインドしたりすることができます.これらのタスクは非同期であっても同期であってもよい.
さらに重要なのは、deferredsが$として機能していることです.ajax()の内部実装なので、AJAXを呼び出すときにdeferredsがもたらす遍歴を自動的に取得できます.たとえば、コールバック関数をバインドできます.
// $.get, AJAX
var req = $.get('foo.htm').success(function (response) {
// AJAX
}).error(function () {
// AJAX
});
// AJAX
doSomethingAwesome();
// AJAX , AJAX ,
// $.ajax deferred ,
req.success(function (response) {
// AJAX , AJAX
});
成功、失敗、または完了したコールバック関数が1つしかないことに制限されません.逆に、これらの随時追加されるコールバック関数は、先進的な先頭キューに配置されます.
上記の例から分かるように、コールバック関数は、AJAX要求(任意の観察可能なタスクobservable task)に付加され、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('I fire once BOTH ajax requests have completed!');
}).fail(function () {
console.log('I fire if one or more requests failed.');
});
jsFiddleでサンプルを開く
上記の例は正常に動作します.これは、各jQueryのAJAXメソッドの戻り値に、非同期要求を追跡するためのpromise関数が含まれているためです.Promise関数の戻り値はdeferredオブジェクトの読み取り専用ビューです.(The promise is a read-only view into the result of the task.)Deferredsは、オブジェクトにpromise()関数が存在するか否かを検出することにより、現在のオブジェクトが観察可能か否かを判断する.$when()は、すべてのAJAXリクエストが終了するのを待って呼び出します.then(), .fail()に登録されたコールバック関数(タスクの終了状態に応じて呼び出されるコールバック関数).これらのコールバック関数は、登録順に実行されます.
もっと良いのは、$.when()は、関数または関数の配列をパラメータとして受け入れます.$.whenは、1つ以上のdeferredオブジェクト、またはオリジナルのJSオブジェクトを受け入れます.関数の配列をパラメータとしてはいけません.これにより、これらの非同期タスクを任意に組み合わせることができます.
$.ajax()は、promise()、then()、success()、error()などのdeferred関数を関連付けたオブジェクトを返します.しかし、元のdeferredオブジェクトを操作することはできません.promise()関数(訳者注:さっき述べたpromiseは読み取り専用ビューであることを覚えています)と、deferred状態を検出できるisRejected()とisResolved()関数だけです.
しかし、なぜdeferredオブジェクトを返さないのですか?完全なdeferredオブジェクトを返すと、より多くの制御があり、任意にトリガーできるかもしれません(訳者注:resolveをトリガーに翻訳すると、deferredオブジェクトに登録されているすべてのコールバック関数がトリガーされます)deferredオブジェクトがトリガーされ、AJAXリクエストが終了する前にすべてのコールバック関数が実行されます.したがって、deferredをトリガするリスクを回避するために、dfdのみを返すべきである.promise().(Therefore, to avoid potentially breaking the whole paradigm, only return the dfd.promise().)(注:もしあなたが上のいくつかの言叶の正确な意味を迷っているならば、大丈夫です.私は后で1篇の文章を书いて深层的にその中の原因を分析してコールバック関数(Registering Callbacks)の上の例を登录して、私达はthen()、success()、fail()方法を使ってコールバック関数を登录して、実は更に多くの方法が使うことができて、特にAJAXの要求を処理する时.具体的にどのような方法を使うかは、結果の状態に対する関心にかかっています.すべてのdeferredオブジェクトにある関数(AJAX,$.whenまたは手動で作成されたdeferredオブジェクト):
.then( doneCallbacks, failedCallbacks )
.done( doneCallbacks )
.fail( failCallbacks )
AJAXオブジェクトには3つの追加のメソッドが含まれています.このうち2つは前述のメソッドにマッピングされます.これらの方法は主に以前のコードと互換性を持つためです.
// "success" "error" "done" and "fail"
.success( doneCallbacks )
.error( failCallbacks )
completeのコールバック関数を登録することもできます.このリクエストが成功したか失敗したかにかかわらず、リクエストが終了した後に呼び出されます.successやerror関数とは異なり、complete関数は実際にはdeferredオブジェクトのdone関数別名です.これは$です.ajax()内部に作成されたdeferredオブジェクトは、AJAXの終了後にコールバック関数(resolve)をトリガーします.
.complete( completeCallbacks )
したがって、次の3つの例は等価です(AJAXのコンテキストでは、successはdone関数よりも楽に見えますよね?)(注:実は私たちが以前のAJAX呼び出し方式を熟知しているため、先入観を主としているだけで、あるいは思考の定勢と呼ばれています):
$.get("/foo/").done( fn );
// :
$.get("/foo/").success( fn );
// :
$.get("/foo/", fn );
独自のdeferredオブジェクトを作成する
私たちは$を知っています.ajaxと$.whenは内部でdeferredインタフェースを実装していますが、deferredオブジェクトを手動で作成することもできます.
function getData() {
return $.get('/foo/');
}
function showDiv() {
var dfd = $.Deferred();
$('#foo').fadeIn(1000, dfd.resolve);
return dfd.promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('The animation AND the AJAX request are both done!');
// 'ajaxResult' ( : getData AJAX )
});
jsFiddleでサンプルを開く
showDiv()では、deferredオブジェクトを作成し、アニメーションを実行してpromiseに戻ります.このdeferredオブジェクトはfadeIn()の終了後にトリガーされます.このpromise戻りとdeferredオブジェクト(注:ここでのdeferredはshowDiv()戻りのオブジェクトではなく$.whenが作成したオブジェクトを指す)がトリガーされる間に、then()コールバック関数が登録されます.このコールバック関数は、2つの非同期タスクがすべて終了した後に実行されます.
getData()は、jQueryパッケージのXMLhttpRequestオブジェクトがpromiseメソッドを持つオブジェクトを返し、$を許可する.when()は今回のAJAXリクエストの終了を監視しています.The manually steps we took to return a promise in showDiv() is handled for us internally by $.ajax() and $.when().
1/15/2011:Julianはコメントの中で、上の文法は$に簡略化することができると指摘した.Deferred(fn).promise().したがって、次の両端コードは等価です.
function showDiv() {
var dfd = $.Deferred();
$('#foo').fadeIn(1000, dfd.resolve);
return dfd.promise();
}
// :
function showDiv() {
return $.Deferred(function (dfd) {
$('#foo').fadeIn(1000, dfd.resolve);
}).promise();
}
カスタムdeferredオブジェクトにコールバック関数(Defer your Deferreds)を追加
さらに、$のようにgetData()とshowDiv()にコールバック関数をそれぞれ登録することができます.then()にコールバック関数を登録するのと同じです.(訳者注:次の段落の内容は繰り返して、すべて1つの意味を言って、翻訳しないで、コードを見ましょう)
function getData() {
return $.get('/foo/').success(function () {
console.log('Fires after the AJAX request succeeds');
});
}
function showDiv() {
return $.Deferred(function (dfd) {
// : , jsFiddle 。
// , deferred
dfd.done(function () {
console.log('Fires after the animation succeeds');
});
$('#foo').fadeIn(1000, dfd.resolve);
}).promise();
}
$.when(getData(), showDiv()).then(function (ajaxResult) {
console.log('Fires after BOTH showDiv() AND the AJAX request succeed!');
// 'ajaxResult'
});
jsFiddleでサンプルを開く
チェーンコード
Deferredのコールバック関数は、deferredオブジェクトが返される限り、チェーンで呼び出すことができます(訳者注:dfd.promise()は読み取り専用のdeferredオブジェクトを返します).これは実際のコードです(via@ajpiano!)
function saveContact(row) {
var form = $.tmpl(templates["contact-form"]),
valid = true,
messages = [],
dfd = $.Deferred();
/*
*
*/
if (!valid) {
dfd.resolve({
success: false,
errors: messages
});
} else {
form.ajaxSubmit({
dataType: "json",
success: dfd.resolve,
error: dfd.reject
});
}
return dfd.promise();
};
saveContact(row).then(function (response) {
if (response.success) {
// ,
} else {
//
//
}
}).fail(function (err) {
// AJAX
});
saveContact()関数は、まずフォームデータの有効性を検証し、変数validに有効性状態を保存します.検証に失敗すると、直接deferredがトリガーされます(successステータスコードとエラーメッセージを含むJSオブジェクトをパラメータとしてコールバック関数に渡します).検証に合格した場合、サーバにデータを送信し、AJAXが正常に完了した後にdeferredオブジェクトをトリガーします.fail()は、AJAXリクエストが正常に完了したHTTPステータスコードを404500など処理します.
観察不可能なタスク(Non-observable Tasks)
Deferredsは、非同期タスクや同期タスクにかかわらず、タスクとタスクの処理関数をデカップリングする場合に便利です.1つのタスクはpromiseを返すかもしれませんが、文字列、オブジェクト、または他のタイプを返すこともできます.
この例では、「Lanch Application」リンクが最初にクリックされると、AJAXリクエストがサーバに送信され、現在のタイムスタンプに戻ります.その後、このタイムスタンプはこのリンクのdataキャッシュに保存されます.このリンクが再びクリックされると、AJAXリクエストを発行せずにキャッシュからこのタイムスタンプを取り出して返すだけです.
function startTask(element) {
var timestamp = $.data(element, 'timestamp');
if (timestamp) {
return timestamp;
} else {
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('You first started this task on: ' + timestamp + '
');
});
loadApplication();
});
$になるwhen()は、最初のパラメータにpromise関数がないことを発見し(したがって観察できません)、新しいdeferredオブジェクトを作成し、deferredオブジェクトをトリガーし、promise読み取り専用オブジェクトに戻ります.したがって、任意の観察不可能なタスクも$に伝達することができる.when()の中.
1つの問題は、オブジェクト自体がpromise関数を持っている場合、このオブジェクトはdeferredオブジェクトとして使用できないことです.jQueryは、オブジェクトがdeferredであるかどうかを判断し、promise関数があるかどうかを確認することによって決定しますが、jQueryはこのpromiseが本当に利用可能なオブジェクトを返すかどうかをチェックしません.次のコードでエラーが発生します.
var obj = {
promise: function () {
// do something
}
};
$.when(obj).then(fn);
結論(Conclusion)
Deferredsは、非同期タスクを処理するための新しい堅牢な方法を提案した.従来のコールバック関数にコードを整理するのとは異なり、新しいdeferredオブジェクトでは、タスクの終了後でもいつでも複数のコールバック関数をバインドできますが、これらのコールバック関数は先進的に呼び出されます.この文章の情報は消化しにくいかもしれませんが、deferredオブジェクトの使用を把握すると、組織が非同期で実行するコードが非常に簡単であることがわかります.
この文章は三生石上オリジナル、ブログ園から先発して、転載して出典を明記してください