在JavaScript
中,方法的链式调用很流行,使用Jquery
的
朋友对此一定深有体会。在《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对象,
然后用它作为工具构建我们的异步方法队列链。有了这个工具,就可以很方便的构建一个从服务器端获取内容并将其附加到选择器中的Jquery
plugin。
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);
}
}
};
这样,我们就可以异步的获取内容,并继续我们的链式调用。
|
(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);
|
查看demo页
看看效果。
如果一个队列中有很多项等待对服务器端的响应进行操作,该如何处置?作者构建了这样一个方法,值得参考:
01
|
function
fetchTweet(url) {
|
02
|
this
.queue =
new
Queue;
|
05
|
ajax(url,
function
(resp)
{
|
07
|
self.queue.flush(
this
);
|
10
|
fetchTweet.prototype = {
|
11
|
linkify:
function
() {
|
12
|
this
.queue.add(
function
(self) {
|
13
|
self.tweet =
self.tweet.replace(/\b@(\w{1,20}\b/g,
'<a href="...">$1</a>'
);
|
17
|
filterBadWords:
function
() {
|
18
|
this
.queue.add(
function
(self) {
|
19
|
self.tweet =
self.tweet.replace(/\b(fuck|shit|piss)\b/g,
""
);
|
23
|
appendTo:
function
(selector)
{
|
24
|
this
.queue.add(
function
(self)
{
|
25
|
$(self.tweet).appendTo(selector);
|
这样,我们就可以用下面的方式来调用:
1
|
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);
|
不知你作如何感想?
转载地址
分享到:
相关推荐
求异步队列的最大执行队列,JavaScript中有多个异步请求,每次最多执行n个(10个),实现一个函数,使每次执行都是最大队列 。 { this.tasks = []; this.max = 10; setTimeout(() => { this.run(); }); }...
然后,按顺序执行队列中的所有回调函数,将结果`resp`作为参数传递。 在实际应用中,我们可以将异步方法(如`$.ajax`)的回调函数与`Queue`对象结合,确保在异步操作完成后,按照预设的顺序执行链式调用中的后续...
`async-fn-queue`库的核心思想是将一系列异步任务放入一个队列中,然后按照指定的规则逐一执行。这有助于确保每个任务在上一个任务完成之后才会开始,防止了资源竞争和潜在的错误。对于需要顺序执行的任务,比如文件...
1. 事件循环(event loop):浏览器会不断地检查事件队列中是否有新的事件,如果有,就将其加入事件队列中。 2. 事件队列(event queue):事件队列是用于存储事件的队列,事件队列中的事件会被逐个执行。 JavaScript中...
当主线程执行栈为空时,事件循环会从异步队列中取出一个任务并执行,然后执行回调函数。Promise的异步处理过程也遵循这一机制,无论是封装同步还是异步函数,Promise都会在适当的时候改变自身的状态,并通过`then`...
JavaScript异步编程是Web开发中的核心技能,它使得开发者能够设计出快速响应的网络应用,提供流畅的用户体验。这本书的源码提供了深入理解和实践这些概念的机会。以下是对这个主题的详细探讨。 首先,我们要理解...
Buzy是一款适用于Node.js和浏览器环境的异步队列管理工具,主要针对JavaScript开发中的并发控制和任务调度问题。在JavaScript编程中,由于其单线程的特性,处理大量并发请求时可能会出现性能瓶颈,而Buzy就是为了...
在上述代码中,`animationQueue`存储了待执行的动画任务,`addAnimationTask`函数用于添加新的动画任务,而`runAnimationQueue`函数则负责按顺序执行队列中的任务。`requestAnimationFrame`用于在浏览器准备好下一次...
当调用栈为空时,事件循环会从消息队列中取出事件并创建一个新的执行上下文,然后将其推入调用栈。在上述示例中,`console.log("Start")`和`console.log("End")`在全局执行上下文中立即执行。`setTimeout`函数创建一...
Vue在内部尝试使用原生的Promise.then和MutationObserver来执行异步队列中的任务,如果执行环境不支持这些特性,会使用setTimeout(fn, 0)来作为替代方案。 Vue.nextTick(callback)是一个非常有用的API,它允许...
在JavaScript编程中,异步处理是至关重要的,尤其是在处理I/O密集型任务或者网络请求时。"异步并行/串行foreach"是这个主题的关键部分,它涉及到如何有效地遍历数组并在每个元素上执行异步操作。在这个场景下,...
JavaScript异步编程是Web开发中的核心概念,尤其在构建交互性强、响应迅速的网页应用时不可或缺。这篇博客“JavaScript异步编程学习”可能探讨了如何有效地处理非阻塞操作,以避免程序因等待I/O或其他耗时任务而陷入...
`enqueue`方法用于向队列中添加函数,如果当前没有异步任务在运行,就会立即执行队列中的第一个函数。每个函数在执行时,如果它是异步的,它会在完成时调用回调,这个回调会清除`isRunning`标志并启动下一个函数。 ...
实现异步队列时,我们需要注意几个关键点: - 确保队列的先进先出(FIFO)原则,即先加入队列的函数或任务应该先被执行。 - 当队列中已经存在正在执行的函数时,新的函数加入应当等待前一个函数执行完毕,再开始...
JavaScript异步编程是Web开发中的核心概念,尤其在构建高性能、响应式的用户界面时不可或缺。JavaScript作为单线程语言,其执行模型决定了它不能同时处理多个任务,而是采用事件循环和回调函数、Promise、async/...
在传统的异步队列中,一旦数据被添加到队列,它就会按照FIFO(先进先出)的原则被处理,而Revocable Queue则增加了灵活性。如果数据还没有被消费,你可以选择撤销它,这在某些情况下是非常有用的,比如处理网络请求...
2. **执行微任务**:在当前执行上下文结束前,清空微队列中的所有任务。 3. **检查宏任务**:执行完所有微任务后,取出宏队列的第一个任务执行。 4. **再次执行微任务**:执行完宏任务后,再次清空微队列,如此循环...
在JavaScript中,有多种异步处理方式,如回调函数、Promise、async/await等。回调函数是最基础的形式,但可能导致回调地狱问题;Promise引入了链式调用和错误处理,改善了回调函数的缺点;async/await是基于Promise...