Jquery高級(jí)應(yīng)用Deferred對(duì)象原理及使用實(shí)例
在實(shí)際開發(fā)中常常遇到這樣的問(wèn)題:B函數(shù)中需要用到的變量或者參數(shù),只有等A函數(shù)執(zhí)行完畢了才能獲取到。比如A函數(shù)中有一個(gè)ajax請(qǐng)求,而B函數(shù)中所需要的position變量需要在A函數(shù)中ajax請(qǐng)求完成才能得到它的準(zhǔn)確值。
function A() {
$.ajax({
url: '/api/test',
type: 'POST',
data: {...},
success: function(res) {
position = res.position;
}
})
}
function B() {
$('.test').text(position);
}
JavaScript的異步模式讓B函數(shù)不會(huì)等待A函數(shù)計(jì)算出了position的值才會(huì)執(zhí)行,它會(huì)不等待A函數(shù)的結(jié)果而直接開始執(zhí)行,這樣就會(huì)造成position無(wú)法正確賦值。為了解決這個(gè)問(wèn)題,我們很容易想到使用回調(diào)函數(shù),這也是最常用的方法之一
function A(callback) {
$.ajax({
url: '/api/test',
type: 'POST',
data: {...},
success: function(res) {
position = res.position;
callback && callback();
}
})
}
function B() {
$('.test').text(position);
}
A函數(shù)有了回調(diào)之后,就可以將B函數(shù)當(dāng)做回調(diào)函數(shù)傳遞給A
A(B);
可是如果這個(gè)時(shí)候,還有一個(gè)C函數(shù),依賴于B的執(zhí)行結(jié)果呢,后面甚至有可能出現(xiàn)一個(gè)D函數(shù),依賴于C的結(jié)果!又如我們常用的ajax,成功了會(huì)有一個(gè)回調(diào)函數(shù),失敗了還有一個(gè)回調(diào)函數(shù),面對(duì)這樣復(fù)雜的情況,我們應(yīng)該怎么樣處理?雖然使用回調(diào)函數(shù)依然能夠搞定這些煩人的難題,但是很顯然這并不是一個(gè)好的解決辦法。
jquery中的Deferred對(duì)象很好的解決了這個(gè)問(wèn)題。在了解Deferred之前,我們可能需要了解一個(gè)JavaScript中的promise模式。當(dāng)我們使用回調(diào)來(lái)解決實(shí)際中的問(wèn)題時(shí),很容易不知不覺中出現(xiàn)代碼金字塔
step1(function() {
step2(function() {
step3(function() {
step4(function() {
step5();
})
})
})
})
假如這個(gè)時(shí)候有一個(gè)js庫(kù)實(shí)現(xiàn)了promise模式,那么我們的代碼就會(huì)變得清晰可讀,并且每一步都會(huì)等待上一步執(zhí)行完畢了才會(huì)執(zhí)行。
new Promise().when(promiseStep1)
.then(promiseStep2)
.then(promiseStep3)
.then(promiseStep4)
.then(promiseStep5);
每一個(gè)promise對(duì)象都可以設(shè)置三種狀態(tài):
- pending [進(jìn)行中]
- resolve [已經(jīng)正確執(zhí)行]
- reject [執(zhí)行失敗]
關(guān)于promise,還有更多需要了解的地方,我這里只是拋磚引玉?;氐絡(luò)Query的Deferred對(duì)象來(lái)。jquery的Deferred對(duì)象就是對(duì)promise模式的一個(gè)很好的實(shí)現(xiàn)案例。我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)看看Deferred對(duì)象應(yīng)該如何使用。
函數(shù)first是一個(gè)耗時(shí)兩秒的操作,而函數(shù)second是一個(gè)簡(jiǎn)單的函數(shù),但是他需要在first執(zhí)行完畢之后才執(zhí)行。
function first() {
setTimeout(function() {
console.log('first');
}, 2000);
}
function second() {
console.log('second');
}
為了達(dá)到second在first之后執(zhí)行,使用Deferred對(duì)first函數(shù)做一個(gè)簡(jiǎn)單的處理即可
function first() {
// 1
var defer = $.Deferred();
setTimeout(function() {
console.log('first');
// 2
defer.resolve();
}, 2000);
// 3
return defer.promise();
}
1、在函數(shù)中聲明一個(gè)Deferred對(duì)象,這樣在外部就無(wú)法修改函數(shù)內(nèi)部的執(zhí)行狀態(tài)
2、函數(shù)執(zhí)行完畢,設(shè)置執(zhí)行狀態(tài),如果成功執(zhí)行,defer.resolve(),如果執(zhí)行失敗,則設(shè)置為defer.reject()
3、在函數(shù)的最后,必須將deferred對(duì)象返回出去,否則外部無(wú)法得到函數(shù)的執(zhí)行結(jié)果
在做了這樣的處理之后,我們就可以滿足要求的正常使用了
$.when(first())
.done(second());
jquery中,ajax方法就是使用promise模式完成的,我們可以看看常規(guī)寫法和Deferred對(duì)象寫法的不同。
// 常規(guī)寫法
$.ajax({
url: '/api/test',
type: 'POST',
data: {...},
success: function(res) {
// dosomething
},
fail: function(res) {
// dosomething
},
complete: function() {
// dosomething
}
})
// 新的寫法
$.ajax({
url: '/api/test',
type: 'POST',
...
})
.done(function(res) {
// success and do something
})
.fail(function(res) {
// fail and do something
})
.always(function() {})
這個(gè)知識(shí)點(diǎn)差不多就總結(jié)完畢了。Promise模式與Deferred對(duì)象都還有更多值得了解知識(shí)點(diǎn)與用法,這是一個(gè)非常值得掌握的神兵利器,建議大家搜索更多的文章來(lái)學(xué)習(xí)它。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于jquery的讓textarea自適應(yīng)高度的插件
jquery extension - auto height text area2010-08-08
jQuery實(shí)現(xiàn)點(diǎn)擊標(biāo)題輸入詳細(xì)信息
點(diǎn)擊標(biāo)題,輸入詳細(xì)信息,點(diǎn)擊確定按鈕,完成,把不必要的選項(xiàng)隱藏,當(dāng)用戶真正有需要的時(shí)候,在顯示出來(lái)2013-04-04
jQuery+Ajax實(shí)現(xiàn)用戶名重名實(shí)時(shí)檢測(cè)
這篇文章主要為大家詳細(xì)介紹了jQuery Ajax實(shí)現(xiàn)用戶名重名實(shí)時(shí)檢測(cè),針對(duì)用戶注冊(cè)時(shí)出現(xiàn)的用戶名重名問(wèn)題進(jìn)行自動(dòng)檢測(cè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
jQuery實(shí)現(xiàn)Meizu魅族官方網(wǎng)站的導(dǎo)航菜單效果
這篇文章主要介紹了jQuery實(shí)現(xiàn)Meizu魅族官方網(wǎng)站的導(dǎo)航菜單效果,可實(shí)現(xiàn)導(dǎo)航菜單項(xiàng)鼠標(biāo)滑過(guò)出現(xiàn)下劃線動(dòng)態(tài)跟隨的功能,通過(guò)jQuery插件實(shí)現(xiàn)該功能,需要的朋友可以參考下2015-09-09
jQuery模擬實(shí)現(xiàn)的select點(diǎn)擊選擇效果【附demo源碼下載】
這篇文章主要介紹了jQuery模擬實(shí)現(xiàn)的select點(diǎn)擊選擇效果,涉及jQuery響應(yīng)鼠標(biāo)點(diǎn)擊動(dòng)態(tài)修改頁(yè)面元素樣式的相關(guān)操作技巧,并附帶demo源碼供讀者下載,需要的朋友可以參考下2016-11-11

