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>

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

WebStorm Mac版
好用的JavaScript開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3 Linux新版
SublimeText3 Linux最新版

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