deferred.promise() および .promise()
これら 2 つの API の構文はほぼ同じですが、大きな違いがあります。 deferred.promise() は Deferred インスタンスのメソッドで、Deferred.Promise インスタンスを返します。 Deferred.Promise オブジェクトは、遅延オブジェクトのビューとして理解できます。これには、done()、then()、fail()、isResolved()、isRejected()、などの遅延オブジェクトのメソッドのセットのみが含まれます。 always() 、これらのメソッドは遅延オブジェクトの状態を観察することのみができますが、遅延オブジェクトの内部状態を変更することはできません。これは API のカプセル化に非常に適しています。たとえば、遅延オブジェクトの所有者は、自分の必要に応じて遅延状態の状態 (解決または拒否) を制御できますが、この遅延オブジェクトの Promise オブジェクトを他のオブザーバーに返すことができ、オブザーバーは、そのオブジェクトを観察することしかできません。対応するコールバック関数は状態を変更しますが、遅延オブジェクトの内部状態を変更することはできないため、適切な分離保護が提供されます。
deferred.promise()
$(function(){ // var deferred = $.Deferred(); var promise = deferred.promise(); var doSomething = function(promise) { promise.done(function(){ alert('deferred resolved.'); }); }; deferred.resolve(); doSomething(promise); })
// Existing object var obj = { hello: function( name ) { alert( "Hello " + name ); } }, // Create a Deferred defer = $.Deferred(); // Set object as a promise defer.promise( obj ); // Resolve the deferred defer.resolve( "John" ); // Use the object as a Promise obj.done(function( name ) { this.hello( name ); // will alert "Hello John" }).hello( "Karl" ); // will alert "Hello Karl"
deferred.promise() は、他のコードがこの遅延オブジェクトの状態を変更するのを防ぐだけです。 deferred.promise() メソッドによって返される遅延 Promise オブジェクトには、状態を変更できる replace、reject、progress、resolveWith、rejectWith、progressWith メソッドが存在せず、done、then、fail などのみを使用できることがわかります。ハンドラーを追加したり、ステータスを判断したりするメソッド。
deferred.promise() は、遅延オブジェクトの状態を変更することはできません。また、現在の状態が変更されないことを保証するものでもありません。これは、deferred によって返される遅延プロミス オブジェクトを通じて遅延オブジェクトの状態を変更できないことを保証するだけです。約束()。ここで dtd を直接返した場合でも、.done 処理関数は dtd.resolve() まで待機してから実行されます。
そのブログの具体的な例で、コードを次の形式に変更するとします。
var dtd = $.Deferred(); // 新建一个deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
そのような実行の結果は、以前に dtd.promise を返した結果と同じです。
違いは何ですか? $.when のコードを次のように変更すると、
var d = wait(dtd); $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); d.resolve();
alert("Haha, success!") はすぐに実行されますが、「実行が完了しました」というメッセージが表示されるまでに 5 秒かかります。
しかし、ここで wait 関数が最終的に dtd.promise() を返した場合、オブジェクト d にはsolve() メソッドがないため、d.resolve() はエラーを報告します。
同様にコードを次のように変更すると、
var dtd = $.Deferred(); // 新建一个deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); }; dtd.resolve(); $.when( wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
また、遅延オブジェクト dtd は wait に渡される前にsolved() されており、遅延オブジェクトが解決または拒否されると、ステータスが完了するため、alert("Haha, success!") がすぐに実行されることもわかります。変わりません。
次に、$.wait コードを次のように変更します。
$.when( wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); dtd.resolve();
また、alert("Haha, success!"); がすぐに実行されることもわかりますが、wait(dtd) が実行されると、dtd は解決されておらず、wait メソッドは dtd.promise() を返します。元の遅延オブジェクト dtd は外部に公開されており、その状態を外部から変更することができます。
したがって、他のコードが wait メソッド内の遅延オブジェクトの状態を変更することを本当に望まない場合は、次のように記述する必要があります:
var wait = function(){ var dtd = $.Deferred(); // 新建一个deferred对象 var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); }; $.when( wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
つまり、deferred を直接公開せず、最終的に deferred.promise() を返すことで、他のコードはハンドラーの追加のみが可能になります。
.promise()
まず第一に、これは Deferred インスタンスのメソッドではありません。 このメソッドはjQueryインスタンスのメソッドです。このメソッドは、一連のタイプのアクション (アニメーションなど) が完了した後に Promise オブジェクトを返し、イベント リスナーがそのステータスを監視し、対応する処理関数を実行するために使用されます。
このメソッドは 2 つのオプションのパラメーターを受け入れます: .promise( [type,] [target] )
type: キューのタイプ。デフォルト値は fx です。fx は jQuery オブジェクトのアニメーションです。
targetObject: Promise 動作を割り当てるオブジェクト、
例: アニメーション効果なしで解決済み状態の Promise オブジェクトを直接返す
var div = $( "<div />" ); div.promise().done(function( arg1 ) { // 将会被马上触发 alert( this === div && arg1 === div ); });
<!DOCTYPE html> <html> <head> <style> div { height: 50px; width: 50px; float: left; margin-right: 10px; display: none; background-color: #090; } </style> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <button>Go</button> <p>Ready...</p> <div></div> <div></div> <div></div> <div></div> <script> $("button").bind( "click", function() { $("p").append( "Started..."); //每个div执行动画效果 $("div").each(function( i ) { $( this ).fadeIn().fadeOut( 1000 * (i+1) ); }); //$("div")包含一组div,在所有的div都完成自己的动画效果后触发done()函数 $( "div" ).promise().done(function() { $( "p" ).append( " Finished! " ); }); }); </script> </body> </html>