Sco*_*den 63 javascript queue ajax jquery design-patterns
我发现有时我需要迭代一些集合并为每个元素进行ajax调用.我希望在转移到下一个元素之前返回每个调用,这样我就不会向服务器发送请求 - 这通常会导致其他问题.我不想将异步设置为false并冻结浏览器.
通常这涉及设置某种迭代器上下文,我逐步通过每个成功回调.我认为必须有一个更简洁的方式?
有没有人有一个聪明的设计模式,如何通过一个集合为每个项目制作ajax调用整齐地工作?
gna*_*arf 111
我开发了一个$.ajaxQueue()
使用了插件$.Deferred
,.queue()
和$.ajax()
也传回一个承诺的请求完成时得到解决.
/*
* jQuery.ajaxQueue - A queue for ajax requests
*
* (c) 2011 Corey Frang
* Dual licensed under the MIT and GPL licenses.
*
* Requires jQuery 1.5+
*/
(function($) {
// jQuery on an empty object, we are going to use this as our Queue
var ajaxQueue = $({});
$.ajaxQueue = function( ajaxOpts ) {
var jqXHR,
dfd = $.Deferred(),
promise = dfd.promise();
// queue our ajax request
ajaxQueue.queue( doRequest );
// add the abort method
promise.abort = function( statusText ) {
// proxy abort to the jqXHR if it is active
if ( jqXHR ) {
return jqXHR.abort( statusText );
}
// if there wasn't already a jqXHR we need to remove from queue
var queue = ajaxQueue.queue(),
index = $.inArray( doRequest, queue );
if ( index > -1 ) {
queue.splice( index, 1 );
}
// and then reject the deferred
dfd.rejectWith( ajaxOpts.context || ajaxOpts,
[ promise, statusText, "" ] );
return promise;
};
// run the actual query
function doRequest( next ) {
jqXHR = $.ajax( ajaxOpts )
.done( dfd.resolve )
.fail( dfd.reject )
.then( next, next );
}
return promise;
};
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
如果您正在使用jQuery 1.4,则可以利用空对象上的动画队列为您的元素的ajax请求创建自己的"队列".
您甚至可以将其纳入您自己的$.ajax()
替代品中.这个插件$.ajaxQueue()
使用jQuery的标准'fx'队列,如果队列尚未运行,它将自动启动第一个添加的元素.
(function($) {
// jQuery on an empty object, we are going to use this as our Queue
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
// hold the original complete function
var oldComplete = ajaxOpts.complete;
// queue our ajax request
ajaxQueue.queue(function(next) {
// create a complete callback to fire the next event in the queue
ajaxOpts.complete = function() {
// fire the original complete if it was there
if (oldComplete) oldComplete.apply(this, arguments);
next(); // run the next query in the queue
};
// run the query
$.ajax(ajaxOpts);
});
};
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
所以,我们有<ul id="items">
一些<li>
我们想要复制(使用ajax!)的<ul id="output">
// get each item we want to copy
$("#items li").each(function(idx) {
// queue up an ajax request
$.ajaxQueue({
url: '/echo/html/',
data: {html : "["+idx+"] "+$(this).html()},
type: 'POST',
success: function(data) {
// Write to #output
$("#output").append($("<li>", { html: data }));
}
});
});
Run Code Online (Sandbox Code Playgroud)
Tho*_*din 13
使用延期承诺的快速小解决方案.虽然这使用jQuery $.Deferred
,但任何其他人都应该这样做.
var Queue = function () {
var previous = new $.Deferred().resolve();
return function (fn, fail) {
return previous = previous.then(fn, fail || fn);
};
};
Run Code Online (Sandbox Code Playgroud)
用法,调用创建新队列:
var queue = Queue();
// Queue empty, will start immediately
queue(function () {
return $.get('/first');
});
// Will begin when the first has finished
queue(function() {
return $.get('/second');
});
Run Code Online (Sandbox Code Playgroud)
请参阅示例,并对异步请求进行并排比较.
归档时间: |
|
查看次数: |
33446 次 |
最近记录: |