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