在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(); }); }...
在javascript中,方法的链式调用很流行,使用jQuery的朋友对此一定深有体会。
async-fn-queue:一个异步函数队列化执行库
一、异步回调二、Promise两者都返回一个 promise 实例,且状态为 fulfilled主线程将回调函数传给异步函数或事件绑定异步队列异步函数或事件回调
buzy用于node和浏览器的异步队列管理器
编辑注:在Review别人的JavaScript代码时曾看到过类似的队列函数,不太理解,原来这个是为了保证函数按顺序调用。读了这篇文章之后,发现还可以用在异步执行等。 假设你有几个函数fn1、fn2和fn3需要按顺序调用,最...
异步队列 asyncQueue = ...参数异步队列采用三个参数: Args Array|null (required)要传递给队列中每个方法的参数数组Queue Array * (必需)要按顺序调用的函数数组。 每个函数都会接收传入的参数和一个额外的ne
主要介绍了单线程JavaScript实现异步过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Revocable Queue允许您异步读取/写入一系列数据值(也称为队列),类似于流或可观察对象。 但是,任何尚未读取的队列中仍未处理的数据/事件都可以被撤销。
队列中的项目被处理为FIFO 。得到它npm i async-limit-queueyarn add async-limit-queue用法首先导入模块并创建一个队列... import createQueue from 'async-limit-queue' ;// this creates a queue with ...
首先,作为单线程语言,在Javascript中定义的任务都会在主线程中执行。但是并不是每个任务都会立刻执行,而这种不立刻执行的任务我们称作异步任务。相反,那些立刻执行的任务我们把它们称作同步任务。而这些异步任务...
一、JavaScript异步编程的两个核心难点 异步I/O、事件驱动使得单线程的JavaScript得以在不阻塞UI的情况下执行网络、文件访问功能,且使之在后端实现了较高的性能。然而异步风格也引来了一些麻烦,其中比较核心的问题...
异步作业的基于承诺的队列@ egoist / promise-queue安装Node.js /纱:yarn add @ egoist / promise-queue对于Node.js / NPM:npm i @ egoist / promise-queue对于Deno:import {PromiseQueue },来自“ ...
从基础的层面来讲,理解JavaScript的定时器是如何工作的是非常重要的。计时器的执行常常和我们的直观想象不同,那是因为JavaScript引擎是单线程的。我们先来认识一下下面三个函数是如何控制计时器的。 var id = ...
异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显。许多不同的方法都可以解决这个问题,本文讨论了一些方法,但并不深入。大家需要...
javascript 异步队列 动机 创建一个处理同步和异步任务的通用任务队列,并遵守队列中条目的顺序。 异步任务使用返回 javascript 承诺的函数处理。 依赖 承诺 polyfill 示例用法 // creating the queue var queue =...
JavaScript程序员如果称一个函数为异步的,其意思就是这个函数会导致将来再运行另一个函数,后者取自于事件队列。如果后面这个函数是作为参数传递给前者的,则称其为回调函数。 callback 回调函数是异步编程最基本的...
JavaScript异步都是通过回调形式完成的,开发过程中一直在处理回调,可能不知不觉中自己就已经处在回调地狱中。 浏览器线程 在开始之前简单的说一下浏览器的线程,对浏览器的作业有个基础的认识。之前说过...