jQuery的Deferred對象能夠簡化異步操作的管理,使代碼更加容易閱讀和維護(hù)。在實(shí)際使用中,可能會(huì)遇到一些需要修改Deferred對象的情況,此時(shí)深入理解Deferred對象的實(shí)現(xiàn)原理就變得尤為重要。
Deferred對象的主要實(shí)現(xiàn)分為兩個(gè)部分,分別為異步操作的任務(wù)隊(duì)列和異步操作的狀態(tài)機(jī)制。任務(wù)隊(duì)列可以將異步操作進(jìn)行串行或并行處理,當(dāng)任務(wù)隊(duì)列中的所有任務(wù)執(zhí)行完成時(shí),就可以觸發(fā)異步完成的回調(diào)函數(shù)。異步操作的狀態(tài)機(jī)制則可以自動(dòng)處理異步操作的狀態(tài)變化,包括等待中、進(jìn)行中和已完成。當(dāng)異步操作完成時(shí),會(huì)根據(jù)異步操作的狀態(tài)自動(dòng)執(zhí)行相應(yīng)的回調(diào)函數(shù)。
// 關(guān)于異步狀態(tài)定義的枚舉值 jQuery.Deferred.prototype = { // 標(biāo)志Deferred對象當(dāng)前狀態(tài)為等待中 state: function () { return this.promise ? this.promise.state() : this._state; }, // 標(biāo)志Deferred對象當(dāng)前狀態(tài)為等待中 always: function () { deferred.done(arguments).fail(arguments); return this; }, // 標(biāo)志Deferred對象當(dāng)前狀態(tài)為等待中,返回一個(gè)新的Deferred對象 then: function () { var fns = arguments; return jQuery.Deferred(function (newDefer) { jQuery.each(tuples, function (i, tuple) { var fn = jQuery.isFunction(funcs[i]) && funcs[i]; deferred[tuple[1]](function () { var returned = fn && fn.apply(this, arguments); if (returned && jQuery.isFunction(returned.promise)) { returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); } else { newDefer[tuple[0] + "With"](this === deferred ? newDefer.promise() : this, fn ? [returned] : arguments); } }); }); tuples = null; }).promise(); }, };
以上的代碼即為jQuery deferred對象的狀態(tài)定義,在其中,$._Deferred()和$.Deferred()實(shí)例化時(shí),可以根據(jù)需求來改變目標(biāo)對象的狀態(tài)。
除了上述代碼之外,Deferred對象還支持許多其他的操作,比如promise()方法用于返回當(dāng)前Deferred對象的promise對象;resolve()方法用于標(biāo)識異步操作已成功完成;reject()方法用于標(biāo)識異步操作已失敗;notify()方法用于通知異步操作的進(jìn)度狀態(tài)等等。因此,深入理解Deferred對象的實(shí)現(xiàn)原理可以讓我們更加靈活地使用Deferred對象,提高代碼的可讀性和可維護(hù)性。