Deferred、Promise、Futureの違いは何ですか?
これら3つすべての背後にある一般的に承認された理論はありますか?
Deferred、Promise、Futureの違いは何ですか?
これら3つすべての背後にある一般的に承認された理論はありますか?
回答:
OPの質問にどのように答えようとしたかに対する明らかな嫌悪感に照らして。文字通りの答えは、プロミスは他のオブジェクトと共有されるものであり、遅延オブジェクトは非公開にする必要があるということです。主に、遅延(通常はPromiseを拡張する)はそれ自体を解決できますが、Promiseは解決できない場合があります。
マニューシャに興味がある場合は、Promises / A +を調べてください。
私の知る限りでは、包括的な目的は、明確化を改善し、標準化されたインターフェースを介して結合を緩めることです。@ jfriend00からの推奨読書を参照してください。
コールバックを関数に直接渡すのではなく、密接に結合されたインターフェイスにつながる可能性があるものをプロミスを使用すると、同期または非同期のコードに対する懸念を分離できます。
個人的には、遅延リクエストは、非同期リクエストによって入力されたテンプレート、依存関係のネットワークを持つスクリプトの読み込み、非ブロック的な方法でデータを形成するためのユーザーフィードバックを提供する場合などに特に役立ちます。
確かに、JSモードで非同期にCodeMirrorをロードした後に何かを行う純粋なコールバック形式を比較してください(申し訳ありませんが、しばらくの間 jQueryを使用していません)。
/* assume getScript has signature like: function (path, callback, context)
and listens to onload && onreadystatechange */
$(function () {
getScript('path/to/CodeMirror', getJSMode);
// onreadystate is not reliable for callback args.
function getJSMode() {
getScript('path/to/CodeMirror/mode/javascript/javascript.js',
ourAwesomeScript);
};
function ourAwesomeScript() {
console.log("CodeMirror is awesome, but I'm too impatient.");
};
});
promisesの公式化されたバージョンに対して(ここでも、申し訳ありませんが、jQueryについては最新ではありません)。
/* Assume getScript returns a promise object */
$(function () {
$.when(
getScript('path/to/CodeMirror'),
getScript('path/to/CodeMirror/mode/javascript/javascript.js')
).then(function () {
console.log("CodeMirror is awesome, but I'm too impatient.");
});
});
準疑似コードについてはお詫びしますが、コアとなるアイデアが多少明確になることを願っています。基本的に、標準化されたプロミスを返すことで、プロミスを渡すことができ、より明確なグループ化が可能になります。
fn(callback, errback)
、密結合や有用性の低下はありませんfn().then(callback, errback)
が、それでもプロミスを使用するには間違った方法です。カーゴカルトの$.when
例は特に嫌いです- $.when
コールバックで機能する関数を使用できない理由はまったくありません。
選択された回答を含むこれらの回答は、概念的にPromiseを導入するのに適していますが、Promiseを実装するライブラリを使用するときに発生する用語に正確にどのような違いがあるかについての詳細はありません(重要な違いがあり ます)。
それはまだ発展中の仕様なので、答えは現在(wikipediaのような)参照と実装(jQueryのような)の両方を調査しようとすることから来ています:
据え置き:
一般的なリファレンスでは説明されていませんが、
1 2 3 4ですが、プロミス解決のアービターとして実装によって一般的に使用されています(実装および)。
5 6 7
resolve
reject
時々のDeferredも約束(実装されているthen
)、
5 6
解像度の繰延ことができるだけを持っているために、より純粋と見られ、および使用するための約束をアクセスするためにユーザーを強制的に相手の回。
7
then
約束:議論中の戦略の最も包括的な用語。
シンクロニシティを抽象化するターゲット関数の結果を格納するプロキシオブジェクト。さらに、then
別のターゲット関数を受け入れて新しいプロミスを返す関数を公開します。
2
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
将来:一部の人気のある参考文献1 と少なくとも1つの人気のある実装 8に見られる廃止予定の用語ですが、 「約束」3という用語が優先され、議論から除外 されているようで、トピックの一般的な紹介では必ずしも言及されていません。 9
ただし、少なくとも1つのライブラリーは、同期性とエラー処理を抽象化するために総称的にこの用語を使用していますが、then
機能は提供していません。
10
「約束」という用語を意図的に避けることは意図的であったかどうかは不明ですが、約束は「実現可能性」を中心に構築されているため、おそらく良い選択です。
2
Promises / AとPromises / A +の違い
(TL; DR、Promises / A +は主にPromises / Aのあいまいさを解決します)
Task
私にとって本当にクリックしたのは、Domenic Denicolaによるこのプレゼンテーションでした。
でgithubのの要旨、彼はほとんどのような説明のIを与え、それは非常に簡潔です。
約束のポイントは、非同期の世界で機能的な構成とエラーのバブリングを返すことです。
つまり、プロミスは、あたかも同期であるかのように簡単に記述できる非同期コードを記述できる方法です。
次の例で、約束を考えてみましょう。
getTweetsFor("domenic") // promise-returning async function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
})
.then(doHttpRequest) // promise-returning async function
.then(
function (responseBody) {
console.log("Most recent link text:", responseBody);
},
function (error) {
console.error("Error with the twitterverse:", error);
}
);
次の同期コードを記述しているかのように機能します。
try {
var tweets = getTweetsFor("domenic"); // blocking
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
console.log("Most recent link text:", responseBody);
} catch (error) {
console.error("Error with the twitterverse: ", error);
}
(これでも複雑に聞こえる場合は、そのプレゼンテーションをご覧ください!)
Deferredに関しては、それは方法.resolve()
または.reject()
約束です。で約束/ Bの仕様、それが呼び出されます.defer()
。jQueryでは$.Deferred()
です。
私の知る限り、jQuery 1.8.2以降では、jQueryでのPromiseの実装が壊れている(その要旨を参照)ことに注意してください。
おそらくPromises / A thenablesを実装していますが、「非同期のtry / catch」機能全体が機能しないという意味で、正しいエラー処理が得られません。これは残念なことです。非同期コードを使用して "試行/キャッチ"を行うのは非常にクールだからです。
Promiseを使用する場合(独自のコードで試してみてください!)、Kris KowalのQを使用してください。jQueryバージョンは、よりクリーンなjQueryコードを作成するためのコールバックアグリゲーターですが、要点を逃しています。
Futureについては、私にはわかりません。どのAPIでもそれを見たことがありません。
編集: 約束のDomenic Denicolaのユーチューブ話から@farm以下のコメント。
ビデオからのマイケルジャクソンからの引用(そう、マイケルジャクソン):
私はあなたにこのフレーズをあなたの心に焼き付けて欲しい: 約束は非同期の値です。
これは優れた説明です。約束は未来からの変数のようなものです。ある時点で存在する(または発生する)ものへのファーストクラスの参照です。
A プロミスは、約束が作成されるときに必ずしも知られていない値のプロキシを表します。ハンドラーを非同期アクションの最終的な成功値または失敗理由に関連付けることができます。これにより、非同期メソッドは同期メソッドのように値を返すことができます。非同期メソッドは、最終的な値の代わりに、将来のある時点で値を持つという約束を返します。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
このdeferred.promise()
メソッドにより、非同期関数は、他のコードがその内部要求の進行またはステータスを妨害するのを防ぐことができます。Promiseは、追加のハンドラーをアタッチするか、状態を決定するために必要なDeferredメソッドのみを公開し(その後、done、fail、always、pipe、progress、state、promise)、状態を変更するメソッド(resolve、reject、notify、resolveWith、 rejectWith、notifyWithなど)。
ターゲットが指定さdeferred.promise()
れている場合、その上にメソッドをアタッチし、新しいオブジェクトを作成するのではなく、このオブジェクトを返します。これは、Promiseビヘイビアーを既存のオブジェクトにアタッチするのに役立ちます。
Deferredを作成する場合は、Deferredへの参照を保持して、ある時点で解決または拒否できるようにします。他のコードがコールバックを登録したり、現在の状態を検査できるように、deferred.promise()を介してPromiseオブジェクトのみを返します。
単純に、Promiseはまだ知られていない値を表し、Deferredはまだ完了していない作業を表すと言えます。
promise
はまだ不明な値を表します deferred
はまだ完了していない作業を表しますpromiseは、最初は不明である結果のプレースホルダーですが、deferredは値をもたらす計算を表します。
参照