ホームページ  >  記事  >  ウェブフロントエンド  >  jQuery_jquery の Deferred の deferred.promise() メソッドの詳細な分析

jQuery_jquery の Deferred の deferred.promise() メソッドの詳細な分析

WBOY
WBOYオリジナル
2016-05-16 15:02:211148ブラウズ

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); 
}) 

deferred.promise() はオブジェクト パラメーターも受け入れることができます。このとき、受信オブジェクトは 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 動作を割り当てるオブジェクト、

これら 2 つのパラメータはオプションです。最初のパラメータ (me) には、現在、fx 以外の他の値タイプが見つかりません。したがって、通常はアニメーションを監視し、アニメーションが完了した後にいくつかの操作を実行するために使用されます。

例: アニメーション効果なしで解決済み状態の Promise オブジェクトを直接返す

var div = $( "<div />" ); 

div.promise().done(function( arg1 ) { 
 // 将会被马上触发 
 alert( this === div && arg1 === div ); 
}); 

例: すべてのアニメーション効果が完了した後に、done() リスニング関数をトリガーします

<!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> 

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