[解決済み] jQuery deferredの "then "メソッドと "pipe "メソッドはいつ使うべきですか?
質問
jQueryの
Deferred
には、関数の非同期連結を実装するために使用できる2つの関数があります。
then()
<ブロッククオート
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks
Deferredが解決された時に呼び出される関数、または関数の配列です。
failCallbacks
Deferredが拒否されたときに呼び出される関数、または関数の配列。
pipe()
<ブロッククオート
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter
Deferredが解決されたときに呼び出されるオプションの関数です。
failFilter
Deferredが拒否されたときに呼び出されるオプションの関数です。
知っている
then()
よりも少し前から存在しています。
pipe()
よりも少し前から存在しているので、後者の方が何か特別な利点があるはずなのですが、その違いが正確には何なのかが私にはわかりません。どちらも名前は違いますが、ほとんど同じコールバック・パラメータを取ります。
Deferred
を返すのと
Promise
はわずかなようです。
私は公式のドキュメントを何度も読みましたが、いつもあまりにも "dense" で、私の頭を本当に包むことができません。検索すると、1 つの機能または他の機能についての多くの議論が見つかりますが、それぞれの異なる利点と欠点を本当に明確にしているものは見つかっていません。
では、どのような場合に
then
を使うのが良いのか、それとも
pipe
?
追加
Felixの素晴らしい回答
のおかげで、この2つの機能がどのように違うのかがとても明確になりました。しかし、私は
then()
よりも
pipe()
.
これは、明らかに
pipe()
よりも強力です。
then()
よりも強力で、前者は後者ができることは何でもできるようです。を使用する理由のひとつは
then()
を使う理由のひとつは、その名前が同じデータを処理する関数の連鎖の終端としての役割を反映しているからかもしれません。
しかし
then()
が元の
Deferred
でできないことを
pipe()
を返すため
Promise
?
どのように解決するのですか?
では
jQuery 1.8
.then
と同じ挙動をします。
.pipe
:
非推奨のお知らせです。 jQuery 1.8より、以下のように
deferred.pipe()
メソッドは非推奨です。このメソッドはdeferred.then()
メソッドを使用する必要があります。
と
jQuery 1.8 時点で を追加しました。
deferred.then()
メソッドは、関数を通して遅延の状態と値をフィルタリングできる新しいプロミスを返し、今では非推奨となっているdeferred.pipe()
メソッドに代わるものです。
以下の例は、まだ一部の人にとって役に立つかもしれません。
これらは異なる目的を果たします。
-
.then()
は、処理の結果、つまりドキュメントに書かれているように、 遅延されたオブジェクトが解決または拒否されたときに、いつでも使用することができます。これは.done()
または.fail()
. -
あなたは
.pipe()
に、(前) フィルタ を実行し、何らかの形で結果を得ることができます。へのコールバックの返り値は.pipe()
への引数として渡されます。done
とfail
のコールバックがあります。また、別の遅延オブジェクトを返すこともでき、以下のコールバックはこの遅延に登録されます。というのは
.then()
(または.done()
,.fail()
) の場合、登録されたコールバックの返り値は単に無視されます。
ですから、あなたが
も
.then()
または
.pipe()
. あなたは
かもしれない
使用
.pipe()
と同じ目的で
.then()
と同じ目的で使用できますが、逆は成り立ちません。
例1
ある操作の結果は、オブジェクトの配列です。
[{value: 2}, {value: 4}, {value: 6}]
で、その値の最小値と最大値を計算したいとします。ここでは、2つの
done
のコールバックを使うとします。
deferred.then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
/* do something with "min" */
}).then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
/* do something with "max" */
});
どちらの場合も、リストに対して反復処理を行い、各オブジェクトから値を抽出する必要があります。
事前に値を抽出しておけば、両方のコールバックで個別に処理する必要がないのでは?はい!そうです。そして、それは私たちが使用できるものです
.pipe()
を使用することができます。
deferred.pipe(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values; // [2, 4, 6]
}).then(function(result) {
// result = [2, 4, 6]
var min = Math.min.apply(Math, result);
/* do something with "min" */
}).then(function(result) {
// result = [2, 4, 6]
var max = Math.max.apply(Math, result);
/* do something with "max" */
});
明らかにこれはでっち上げの例で、この問題を解決する多くの異なる(たぶんより良い)方法がありますが、ポイントを説明していることを望みます。
例 2
Ajaxの呼び出しについて考えてみましょう。時には、前の呼び出しが完了した後に、1つのAjaxの呼び出しを開始したい場合があります。一つの方法は、2回目の呼び出しを
done
コールバックの中で2回目の呼び出しを行うことです。
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
さて、コードを分離して、これら2つのAjaxコールを関数内に置きたいと仮定してみましょう。
function makeCalls() {
// here we return the return value of `$.ajax().done()`, which
// is the same deferred object as returned by `$.ajax()` alone
return $.ajax(...).done(function() {
// executed after first call
$.ajax(...).done(function() {
// executed after second call
});
});
}
を呼び出す他のコードに、遅延オブジェクトを使用したいと思います。
makeCalls
を呼び出す他のコードに
第二
Ajaxの呼び出しですが
makeCalls().done(function() {
// this is executed after the first Ajax call
});
の中で呼び出されるため、期待される効果は得られません。
done
コールバックの内部で行われ、外部からはアクセスできないためです。
解決策としては
.pipe()
を使うことです。
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object and connected to the one returned
// by the callback passed to `pipe`
return $.ajax(...).pipe(function() {
// executed after first call
return $.ajax(...).done(function() {
// executed after second call
});
});
}
makeCalls().done(function() {
// this is executed after the second Ajax call
});
を使うことで
.pipe()
を使うことで、呼び出しの実際のフロー/順序を公開することなく、コールバックを "inner" Ajax 呼び出しに追加することができるようになりました。
一般的に、遅延オブジェクトはコードを切り離すための興味深い方法を提供します。)
関連
-
[解決済み] jQueryのディファレンシャルとプロミス - .then() vs .done()
-
[解決済み] ユーザーがDIVの外側をクリックしたときに、jQueryを使用してDIVを非表示にする
-
[解決済み] jQueryを使って要素のIDを取得するにはどうすればよいですか?
-
[解決済み] 画面サイズ、現在のウェブページ、ブラウザウィンドウのサイズを取得する
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] セレクトボックスのオプションをすべて削除してから、オプションを1つ追加して、jQueryで選択するにはどうすればよいですか?
-
[解決済み] Reduxの非同期フローになぜミドルウェアが必要なのか?
-
[解決済み] jQuery に何かを実行する前にすべての画像の読み込みを待つように指示する公式な方法
-
[解決済み] jQueryを使用して配列から特定の値を削除する方法
-
[解決済み】jQuery.ajaxのcontinueレスポンスの処理。"success:" vs ".done"?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] jQueryのディファレンシャルとプロミス - .then() vs .done()
-
echarts-all.js:1 Uncaught TypeError: nullのプロパティ'getAttribute'を読み取ることができません。
-
[解決済み] クラスメソッド内の "this "をタイプスクリプトで記述する
-
[解決済み] JavaScript - 二重引用符のエスケープ
-
[解決済み] ドロップダウンのアイテムの選択値をjQueryで取得する
-
[解決済み] jQueryでval()がchange()をトリガーしない
-
[解決済み] jQuery: テキストで要素を検索する
-
[解決済み] jQueryのn番目の要素を取得する方法
-
[解決済み】jQueryがリクエストボディに有効なjsonを投稿する。
-
[解決済み】jQueryでRSSをパースする。