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