JavaScript 異步方法隊列鏈實現(xiàn)代碼分析
在《javascript設(shè)計模式》中對這種方法作了比較詳細的描述,實現(xiàn)方法的鏈式調(diào)用,只須讓在原型中定義的方法都返回調(diào)用這些方法的實例對象的引用即可,看看書中的這段代碼:
(function() {
function _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; ++i) {
var element = els[i];
if (typeof element == 'string') {
element = document.getElementById(element);
}
this.elements.push(element);
}
};
_$.prototype = {
each: function(fn) {
for ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(this, this.elements[i]);
}
return this;
},
setStyle: function(prop, val) {
this.each(function(el) {
el.style[prop] = val;
});
return this;
},
show: function() {
var that = this;
this.each(function(el) {
that.setStyle('display', 'block');
});
return this;
},
addEvent: function(type, fn) {
var add = function(el) {
if (window.addEventListener) {
el.addEventListener(type, fn, false);
}
else if (window.attachEvent) {
el.attachEvent('on'+type, fn);
}
};
this.each(function(el) {
add(el);
});
return this;
}
};
window.$ = function() {
return new _$(arguments);
};
})();
可以看到,每個方法都以”return this”結(jié)束,這就會將調(diào)用方法的對象傳遞給鏈上的下一個方法。但是,如果我們要操作的數(shù)據(jù)是通過異步請求來獲得的,如何保持方法的鏈式調(diào)用呢?Dustin Diaz為我們提供了一種方法來保證方法的鏈式調(diào)用,他也是《javascript設(shè)計模式》一書的作者之一。
他首先構(gòu)建了一個Queue對象,即:
function Queue() {
// store your callbacks
this._methods = [];
// keep a reference to your response
this._response = null;
// all queues start off unflushed
this._flushed = false;
}
Queue.prototype = {
// adds callbacks to your queue
add: function(fn) {
// if the queue had been flushed, return immediately
if (this._flushed) {
fn(this._response);
// otherwise push it on the queue
} else {
this._methods.push(fn);
}
},
flush: function(resp) {
// note: flush only ever happens once
if (this._flushed) {
return;
}
// store your response for subsequent calls after flush()
this._response = resp;
// mark that it's been flushed
this._flushed = true;
// shift 'em out and call 'em back
while (this._methods[0]) {
this._methods.shift()(resp);
}
}
};
然后用它作為工具構(gòu)建我們的異步方法隊列鏈。有了這個工具,就可以很方便的構(gòu)建一個從服務(wù)器端獲取內(nèi)容并將其附加到選擇器中的jQuery plugin。
(function($) {
$.fn.fetch = function(url) {
var queue = new Queue;
this.each(function() {
var el = this;
queue.add(function(resp) {
$(el).html(resp);
});
});
$.ajax({
url: url,
dataType: 'html',
success: function(html) {
queue.flush(html);
}
});
return this;
};
})(jQuery);
這樣,我們就可以異步的獲取內(nèi)容,并繼續(xù)我們的鏈式調(diào)用。
$("<div/>")
.fetch('/server/navigation.html')
.addClass('column')
.appendTo('#side');
查看demo頁看看效果。
如果一個隊列中有很多項等待對服務(wù)器端的響應(yīng)進行操作,該如何處置?作者構(gòu)建了這樣一個方法,值得參考:
function fetchTweet(url) {
this.queue = new Queue;
this.tweet = "";
var self = this;
ajax(url, function(resp) {
self.tweet = resp;
self.queue.flush(this);
});
}
fetchTweet.prototype = {
linkify: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/\b@(\w{1,20}\b/g, '$1');
});
return this;
},
filterBadWords: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/\b(fuck|shit|piss)\b/g, "");
});
return this;
},
appendTo: function(selector) {
this.queue.add(function(self) {
$(self.tweet).appendTo(selector);
});
return this;
}
};
這樣,我們就可以用下面的方式來調(diào)用:
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
到此,我們已經(jīng)知道了如何實現(xiàn)異步方法鏈式調(diào)用,但在《Asynchronous method queue chaining in JavaScript》底部的一些評論提出的一些問題,值得思考一下。插件$.fn.fetch中僅僅只需將返回的內(nèi)容附加到元素之中,Queue是否必要?而且,jQuery中的$.fn.load完全可以實現(xiàn),如果Queue中只用一個回調(diào)函數(shù),完全可以這樣來寫:
(function($) {
$.fn.fetch = function(url) {
var queue = new Queue;
this.each(function() {
var el = this;
$.ajax({
url: url,
type: 'get',
dataType: 'json',
success: function(resp) {
$(el).html(resp['text1']);
}
});
});
return this;
};
})(jQuery);
不知你作如何感想?
- JS異步宏隊列微隊列原理詳解
- JS異步宏隊列與微隊列原理區(qū)別詳解
- 淺談Vuejs中nextTick()異步更新隊列源碼解析
- JS異步函數(shù)隊列功能實例分析
- JavaScript隊列函數(shù)和異步執(zhí)行詳解
- JavaScript錯誤處理try..catch...finally+涵蓋throw+TypeError+RangeError
- 聊聊Javascript中try catch的2個作用
- 一分鐘學(xué)會JavaScript中的try-catch
- 實例解析js中try、catch、finally的執(zhí)行規(guī)則
- JavaScript異步隊列進行try?catch時的問題解決
相關(guān)文章
javascript實現(xiàn)文本框標簽驗證的實例代碼
這篇文章主要介紹了javascript實現(xiàn)文本框標簽驗證的實例代碼,需要的朋友可以參考下2018-10-10深入理解JavaScript系列(15) 函數(shù)(Functions)
本章節(jié)我們要著重介紹的是一個非常常見的ECMAScript對象——函數(shù)(function),我們將詳細講解一下各種類型的函數(shù)是如何影響上下文的變量對象以及每個函數(shù)的作用域鏈都包含什么,以及回答諸如像下面這樣的問題:下面聲明的函數(shù)有什么區(qū)別么2012-04-04JavaScript的類型轉(zhuǎn)換(字符轉(zhuǎn)數(shù)字 數(shù)字轉(zhuǎn)字符)
不能把JavaScript中的類型轉(zhuǎn)換看作為強制類型轉(zhuǎn)換。2010-08-08JavaScript 輪播圖和自定義滾動條配合鼠標滾輪分享代碼貼
本文給大家分享一段js輪播圖和自定義滾動條的代碼片段,布局和樣式小編沒給大家多介紹,大家可以根據(jù)個人需求優(yōu)化,具體實現(xiàn)代碼,大家可以參考下面代碼片段2016-10-10ionic App問題總結(jié)系列之ionic點擊系統(tǒng)返回鍵退出App
本篇文章主要介紹了ionic App問題總結(jié)系列之ionic點擊系統(tǒng)返回鍵退出App,具有一定的參考價值,有興趣的可以了解一下2017-08-08JavaScript函數(shù)式編程(Functional Programming)組合函數(shù)(Composition)用法分析
這篇文章主要介紹了JavaScript函數(shù)式編程(Functional Programming)組合函數(shù)(Composition)用法,結(jié)合實例形式分析了javascript函數(shù)式編程中組合函數(shù)的概念、原理、用法及操作注意事項,需要的朋友可以參考下2019-05-05值得學(xué)習(xí)的JavaScript調(diào)試技巧分享
這篇文章主要給大家介紹了一些JavaScript調(diào)試技巧,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06