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

深入解析jQuery中Deferred的deferred.promise()方法_jquery

May 16, 2016 pm 03:02 PM
javascript jquery js promise

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

熱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 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

建議:優秀JS開源人臉偵測辨識項目 建議:優秀JS開源人臉偵測辨識項目 Apr 03, 2024 am 11:55 AM

建議:優秀JS開源人臉偵測辨識項目

jQuery中如何使用PUT請求方式? jQuery中如何使用PUT請求方式? Feb 28, 2024 pm 03:12 PM

jQuery中如何使用PUT請求方式?

jQuery如何移除元素的height屬性? jQuery如何移除元素的height屬性? Feb 28, 2024 am 08:39 AM

jQuery如何移除元素的height屬性?

jQuery小技巧:快速修改頁面所有a標籤的文本 jQuery小技巧:快速修改頁面所有a標籤的文本 Feb 28, 2024 pm 09:06 PM

jQuery小技巧:快速修改頁面所有a標籤的文本

使用jQuery修改所有a標籤的文字內容 使用jQuery修改所有a標籤的文字內容 Feb 28, 2024 pm 05:42 PM

使用jQuery修改所有a標籤的文字內容

js和vue的關係 js和vue的關係 Mar 11, 2024 pm 05:21 PM

js和vue的關係

JS 的 AI 時代來了! JS 的 AI 時代來了! Apr 08, 2024 am 09:10 AM

JS 的 AI 時代來了!

了解jQuery中eq的作用及應用場景 了解jQuery中eq的作用及應用場景 Feb 28, 2024 pm 01:15 PM

了解jQuery中eq的作用及應用場景

See all articles