JavaScript 非同步方法呼叫隊列鏈實現程式碼分析

來源:互聯網
上載者:User

在《javascript設計模式》中對這種方法作了比較詳細的描述,實現方法的鏈式調用,只須讓在原型中定義的方法都返回調用這些方法的執行個體對象的引用即可,看看書中的這段代碼:

複製代碼 代碼如下:(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”結束,這就會將調用方法的對象傳遞給鏈上的下一個方法。但是,如果我們要操作的資料是通過非同步請求來獲得的,如何保持方法的鏈式調用呢?Dustin Diaz為我們提供了一種方法來保證方法的鏈式調用,他也是《javascript設計模式》一書的作者之一。
他首先構建了一個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);
}
}
};

然後用它作為工具構建我們的非同步方法呼叫隊列鏈。有了這個工具,就可以很方便的構建一個從伺服器端擷取內容並將其附加到選取器中的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);

這樣,我們就可以非同步擷取內容,並繼續我們的鏈式調用。 複製代碼 代碼如下:$("<div/>")
.fetch('/server/navigation.html')
.addClass('column')
.appendTo('#side');

查看demo頁看看效果。
如果一個隊列中有很多項等待對伺服器端的響應進行操作,該如何處置?作者構建了這樣一個方法,值得參考: 複製代碼 代碼如下: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;
}
};

這樣,我們就可以用下面的方式來調用: 複製代碼 代碼如下:fetchTweet(url).linkify().filterBadWords().appendTo('#status');

到此,我們已經知道了如何?非同步方法呼叫鏈式調用,但在《Asynchronous method queue chaining in JavaScript》底部的一些評論提出的一些問題,值得思考一下。外掛程式$.fn.fetch中僅僅只需將返回的內容附加到元素之中,Queue是否必要?而且,jQuery中的$.fn.load完全可以實現,如果Queue中只用一個回呼函數,完全可以這樣來寫:複製代碼 代碼如下:(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);

不知你作如何感想?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.