搜尋
首頁web前端js教程深入解析jQuery中Deferred的deferred.promise()方法_jquery

deferred.promise() 和 .promise()

這兩個API語法幾乎一樣,但有著很大的差異。 deferred.promise()是Deferred實例的一個方法,他傳回一個Deferred.Promise實例。一個Deferred.Promise物件可以理解為是deferred物件的視圖,它只包含deferred物件的一組方法,包括:done(),then(),fail(),isResolved(), isRejected(), always() ,這些方法只能觀察一個deferred的狀態,而無法改變deferred物件的內在狀態。這非常適合於API的封裝。例如一個deferred物件的持有者可以根據自己的需求控制deferred狀態的狀態(resolved或rejected),但是可以把這個deferred物件的Promise物件回傳給其它的觀察者,觀察者只能觀察狀態的變化綁定對應的回呼函數,但是無法更改deferred物件的內在狀態,從而起到很好的隔離保護作用。

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()也可以接受一個object參數,此時傳入的object將被賦予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 物件的狀態。可以理解成,透過deferred.promise() 方法返回的deferred promise 對象,是沒有resolve ,reject, progress , resolveWith, rejectWith , progressWith 這些可以改變狀態的方法,你只能使用done, then ,fail 等方法添加handler或判斷狀態。

deferred.promise() 改變不了 deferred 物件的狀態,作用也不是保證目前的狀態不變,它只是保證你不能透過 deferred.promise() 傳回的 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(“哈哈,成功了!”) 會立即執行,“執行完畢”卻需要5秒後才彈出來。

但是如果我們 wait 函數最後是 return dtd.promise() 這裡 d.resolve() 就會報錯了,因為物件 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("出错啦!"); });

我們也可以發現alert(“哈哈,成功了!”) 會立即執行,因為dtd 這個deferred 物件在被傳入wait 之前,已經被resolve() 了,而deferred 物件一旦被resolve 或者reject 之後,狀態是不會改變的。

然後我們再把 $.wait 這塊的程式碼改成:

$.when( wait(dtd))
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出错啦!"); });
dtd.resolve();

我們也會發現alert(“哈哈,成功了!”); 被立即執行,雖然wait(dtd) 執行的時候, dtd 還沒有被resolve,而且wait 方法返回的是dtd.promise(), 但是dtd 這個原始的deferred 物件是暴露在外面的,我們還是可以從外面改變它的狀態。

於是,如果我們真的不想讓其他程式碼能改變 wait 方法內部的 deferred 物件的狀態,那我們應該寫成這樣:

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() ,讓其他地方的程式碼只能加上 handler 。


.promise()

首先這不是Deferred實例的方法! 該方法是jQuery實例的方法。此方法用於一組類型的動作(例如動畫)全部完成後返回一個Promise對象,供事件監聽器監聽其狀態並執行相應的處理函數。

此方法接受兩個可選參數:.promise( [type,] [target] )

type:隊列的類型,預設值是fx,fx即jQuery物件的動畫.
targetObject :要賦予Promise行為的對象,

這兩個參數是可選的。其中第一個參數(我)目前除了fx還沒有找到其他的值類型。因此一般都是用於動畫的監控,在動畫完成後做一些操作。

範例:沒有動畫效果直接回傳一個resolved狀態的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
jquery实现多少秒后隐藏图片jquery实现多少秒后隐藏图片Apr 20, 2022 pm 05:33 PM

实现方法:1、用“$("img").delay(毫秒数).fadeOut()”语句,delay()设置延迟秒数;2、用“setTimeout(function(){ $("img").hide(); },毫秒值);”语句,通过定时器来延迟。

jquery怎么修改min-height样式jquery怎么修改min-height样式Apr 20, 2022 pm 12:19 PM

修改方法:1、用css()设置新样式,语法“$(元素).css("min-height","新值")”;2、用attr(),通过设置style属性来添加新样式,语法“$(元素).attr("style","min-height:新值")”。

axios与jquery的区别是什么axios与jquery的区别是什么Apr 20, 2022 pm 06:18 PM

区别:1、axios是一个异步请求框架,用于封装底层的XMLHttpRequest,而jquery是一个JavaScript库,只是顺便封装了dom操作;2、axios是基于承诺对象的,可以用承诺对象中的方法,而jquery不基于承诺对象。

jquery怎么在body中增加元素jquery怎么在body中增加元素Apr 22, 2022 am 11:13 AM

增加元素的方法:1、用append(),语法“$("body").append(新元素)”,可向body内部的末尾处增加元素;2、用prepend(),语法“$("body").prepend(新元素)”,可向body内部的开始处增加元素。

jquery中apply()方法怎么用jquery中apply()方法怎么用Apr 24, 2022 pm 05:35 PM

在jquery中,apply()方法用于改变this指向,使用另一个对象替换当前对象,是应用某一对象的一个方法,语法为“apply(thisobj,[argarray])”;参数argarray表示的是以数组的形式进行传递。

jquery怎么删除div内所有子元素jquery怎么删除div内所有子元素Apr 21, 2022 pm 07:08 PM

删除方法:1、用empty(),语法“$("div").empty();”,可删除所有子节点和内容;2、用children()和remove(),语法“$("div").children().remove();”,只删除子元素,不删除内容。

jquery怎么去掉只读属性jquery怎么去掉只读属性Apr 20, 2022 pm 07:55 PM

去掉方法:1、用“$(selector).removeAttr("readonly")”语句删除readonly属性;2、用“$(selector).attr("readonly",false)”将readonly属性的值设置为false。

jquery on()有几个参数jquery on()有几个参数Apr 21, 2022 am 11:29 AM

on()方法有4个参数:1、第一个参数不可省略,规定要从被选元素添加的一个或多个事件或命名空间;2、第二个参数可省略,规定元素的事件处理程序;3、第三个参数可省略,规定传递到函数的额外数据;4、第四个参数可省略,规定当事件发生时运行的函数。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。