摘要:比較下和也就是說返回值是的一個非狀態操作的子集,允許我們添加回調,但是不允許我們操作的狀態。前面說了的返回值是一個新的對象,如果在新的對象上繼續添加回調會怎么樣呢我們分兩種情況來看。方法的返回值不是對象的返回值會傳遞給的參數。
前言
Deferred是從1.5版本引入的一個核心特性之一,主要是為了解決Callback Hell,老生常談的問題,這里就不多贅述了。本文旨在剖析Deferred的內部實現,讓大家能夠深入了解Deferred。
API $.Deferred通過調用$.Deferred()獲取到一個Deferred實例,如下
var dd = $.Deferred();
調用的時候可以傳入一個函數(可以簡單的看作構造函數),如下
var dd = $.Deferred(function (newDefer) { newDefer.name = "My Deferred"; }); console.log(dd.name);//My Deferredresolve/done reject/fail notify/progress
Deferred的實現使用了閉包,內部維護了三個$.Callbacks管理隊列。
可以說Deferred的核心在于$.Callbacks。如果不熟悉$.Callbacks的請自行搜索或參考我的另一篇介紹文章jQuery Callbacks。代碼可以簡化成下面的樣子
var resolveCb = jQuery.Callbacks("once memory"); var rejectCb = jQuery.Callbacks("once memory"); var notifyCb = jQuery.Callbacks("memory"); done = resolveCb.add resolve ~ resolveCb.fire resolveWith = resolveCb.fireWith fail = rejectCb.add reject ~ rejectCb.fire rejectWith = rejectCb.fireWith progress = notifyCb.add notify ~ notifyCb.fire notifyWith = notifyCb.fireWith
~表示可以簡單理解為對等。我們再看看下面的代碼會不會有不一樣的感覺了
var dd = $.Deferred(); dd.done(function (name) { console.log(name, 1); }).done(function (name) { console.log(name, 2); }); dd.resolve("Jacky");
其實就相當于
resolveCb.add(function (name) { console.log(name, 1); }).add(function (name) { console.log(name, 2); }); resolveCb.fire("Jacky");
當Deferred執行完resolve以后,同時會調用rejectCb.disable和notifyCb.lock。
當Deferred執行完reject以后,同時會調用resolveCb.disable和notifyCb.lock。
notifyCb就是一個單純的$.Callbacks,但是它的狀態會受到resolve/reject的影響。
resolve/resolveWith reject/rejectWith notify/notifyWithresolveCb和rejectCb兩者之間是相互限制的,一旦兩者中的某一個fire了,另一個就會被disable。通過這種方式來達到唯一狀態。
就是fire和firewith的區別
state返回Deferred的當前狀態,總共有三種狀態
執行resolve/reject前,返回值是pending
執行了resolve,返回值是resolved
執行了reject,返回值是rejected
var dd = $.Deferred();
console.log(dd.state());//pending
dd.resolve();
console.log(dd.state());//resolved
//dd.reject();
//console.log(dd.state());//rejected
看下源碼大家就一清二楚了
還是調用的done和fail,往各自隊列里添加回調。
提供Deferred的非狀態接口。比較下Deferred和Deferred.promise()
var dd = $.Deferred(); var promise = dd.promise(); console.log(dd); console.log(promise);
也就是說promise返回值是Deferred的一個非狀態操作的子集,允許我們添加回調,但是不允許我們操作Deferred的狀態。也可以將這些方法添加到某一個對象上,例如
var obj = {name: "xxx"}; var dd = $.Deferred(); var newObj = dd.promise(obj); console.log(newObj); console.log(newObj === obj);then/pipe
pipe是為了向下兼容留下的方法,pipe===then。then支持三個參數,返回值是一個新的promise對象。看幾個例子
例子一var dd = $.Deferred(); dd.done(function (name) { console.log("dd", name); }); dd.then(function (name) { console.log("then", name); }); dd.resolve("Jacky"); //dd Jacky //then Jacky例子二
var dd = $.Deferred(); dd.fail(function (name) { console.log("dd", name); }); dd.then(null, function (name) { console.log("then", name); }); dd.reject("Jacky"); //dd Jacky //then Jacky例子三
var dd = $.Deferred(); dd.progress(function (name) { console.log("dd", name); }); dd.then(null, null, function (name) { console.log("then", name); }); dd.notify("Jacky"); //dd Jacky //then Jacky
三個參數剛好分別添加到了內部的三個回調隊列中。dd.then(fn)可以簡單看作dd.done(fn)。前面說了then的返回值是一個新的promise對象,如果在新的Deferred對象上繼續添加回調會怎么樣呢?我們分兩種情況來看。
then方法的返回值不是Deferred對象var dd = $.Deferred(); var newdd = dd.then(function (name) { console.log("then", name); return "Mary"; }); newdd.done(function (name) { console.log("newDefer", name); }); dd.resolve("Jacky"); //then Jacky //newDefer Mary
then的返回值會傳遞給done/fail的參數。而且無需我們手動調用newdd.resolve,內部幫我們調用了
返回值是Deferred對象看個例子
var dd = $.Deferred(); var returndd = $.Deferred();
var newdd = dd.then(function (name) { console.log("then", name); return returndd; }); newdd.done(function (name) { console.log("newDefer", name); }); dd.resolve("Jacky");//then Jacky
newdd.done添加的函數沒有馬上執行了。我們手動調用下returndd.resolve
var dd = $.Deferred(); var returndd = $.Deferred();
var newdd = dd.then(function (name) { console.log("then", name); return returndd; }); newdd.done(function (name) { console.log("newDefer", name); }); dd.resolve("Jacky");//then Jacky returndd.resolve("Helen");//newDefer Helen
這里就是我們的promise編程了
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78538.html
摘要:中文文檔簡單說,對象就是的回調函數解決方案。為了讓回調函數的名字統一,便于在中使用。普通操作的回調函數接口對象的最大優點,就是它把這一套回調函數接口,從操作擴展到了所有操作。指定操作成功時的回調函數。 參考鏈接 jQuery API中文文檔 jQuery.Deferred jQuery.when jQuery的deferred對象詳解 jQuery deferred 對象的 prom...
摘要:通常的做法是,為它們指定回調函數。指定操作成功時的回調函數指定操作失敗時的回調函數沒有參數時,返回一個新的對象,該對象的運行狀態無法被改變接受參數時,作用為在參數對象上部署接口。 jQuery的開發速度很快,幾乎每半年一個大版本,每兩個月一個小版本。 每個版本都會引入一些新功能。今天我想介紹的,就是從jQuery 1.5.0版本開始引入的一個新功能----deferred對象。 這個功...
摘要:和和都有和,但是略有不同。實際上返回的是一個對象。和添加的回調,添加的回調。所以在調用成功的情況下執行添加的回調,調用失敗時執行添加的回調。,產生對象并,產生對象并,然后繼續處理,的語法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不過它們的作用可以簡單的用兩句話來描述 Deffere...
摘要:通常的做法是,為它們指定回調函數。簡單說,對象就是的回調函數解決方案。指定操作成功時的回調函數指定操作失敗時的回調函數沒有參數時,返回一個新的對象,該對象的運行狀態無法被改變接受參數時,作用為在參數對象上部署接口。 轉自:阮一峰:http://www.ruanyifeng.com/blo... 一、什么是deferred對象?開發網站的過程中,我們經常遇到某些耗時很長的javascri...
摘要:回調隊列對象,用于構建易于操作的回調函數集合,在操作完成后進行執行。對象對象,用于管理回調函數的多用途列表。如果傳入一個延遲對象,則返回該對象的對象,可以繼續綁定其余回調,在執行結束狀態之后也同時調用其回調函數。 在工作中我們可能會把jQuery選擇做自己項目的基礎庫,因為其提供了簡便的DOM選擇器以及封裝了很多實用的方法,比如$.ajax(),它使得我們不用操作xhr和xdr對象,直...
摘要:我們稱為回調對象,它內部會維護一個數組,我們可以向其中添加若干個回調函數,然后在某一條件下觸發執行。第一次之后,再次新的回調函數時,自動執行回調。當前面的回調函數返回時,終止后面的回調繼續執行。 最近懶癌發作,說好的系列文章,寫了一半,一直懶得寫,今天補上一篇。 Deferred 我們在使用promise對象時,總會提到一個與它關系密切的對象——Deferred。其實Deferred沒...
閱讀 1892·2021-11-23 09:51
閱讀 1535·2021-11-19 09:40
閱讀 3209·2021-11-11 11:01
閱讀 1105·2021-09-27 13:34
閱讀 1835·2021-09-22 15:56
閱讀 2122·2019-08-30 15:52
閱讀 1061·2019-08-30 14:13
閱讀 3473·2019-08-30 14:10