MBa*_*Bax 54 queue ajax jquery
我第一次使用jQuery.queue()并且还没有完全掌握它.有人可以指出我做错了什么吗?
看着firebug,我仍然看到我的POST请求同时被触发 - 所以我想知道我是否在错误的地方调用dequeue().
另外 - 我怎样才能获得队列长度?
我需要对这些请求进行排队的原因是,单击按钮会触发它.并且用户可以快速连续点击多个按钮.
试图剥离我的代码的基本结构:
$("a.button").click(function(){
$(this).doAjax(params);
});
// method
doAjax:function(params){
$(document).queue("myQueueName", function(){
$.ajax({
type: 'POST',
url: 'whatever.html',
params: params,
success: function(data){
doStuff;
$(document).dequeue("myQueueName");
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
jAn*_*ndy 87
你的问题在于,它.ajax()会触发异步运行的Ajax请求.这意味着,.ajax()立即返回,非阻塞.所以你的队列功能,但它们几乎会像你描述的那样同时发射.
我不认为这.queue()是一个有ajax请求的好地方,它更适合使用fx methods.你需要一个简单的经理.
var ajaxManager = (function() {
var requests = [];
return {
addReq: function(opt) {
requests.push(opt);
},
removeReq: function(opt) {
if( $.inArray(opt, requests) > -1 )
requests.splice($.inArray(opt, requests), 1);
},
run: function() {
var self = this,
oriSuc;
if( requests.length ) {
oriSuc = requests[0].complete;
requests[0].complete = function() {
if( typeof(oriSuc) === 'function' ) oriSuc();
requests.shift();
self.run.apply(self, []);
};
$.ajax(requests[0]);
} else {
self.tid = setTimeout(function() {
self.run.apply(self, []);
}, 1000);
}
},
stop: function() {
requests = [];
clearTimeout(this.tid);
}
};
}());
Run Code Online (Sandbox Code Playgroud)
这远非完美,我只是想展示出去的方式.以上示例可以以类似的方式使用
$(function() {
ajaxManager.run();
$("a.button").click(function(){
ajaxManager.addReq({
type: 'POST',
url: 'whatever.html',
data: params,
success: function(data){
// do stuff
}
});
});
});
Run Code Online (Sandbox Code Playgroud)
dig*_*rld 13
我需要做类似的事情,以为我会在这里发布我的解决方案.
基本上我所拥有的是一个页面,其中列出了所有具有独特标准的货架上的项目.我想逐个加载货架,而不是完全加载一些内容给用户更快,他们可以看到其他内容加载.
基本上我将每个架子的ID存储在JS数组中,我在从PHP调用它时使用它.
然后我创建了一个递归函数,它会在每次调用时弹出数组中的第一个索引,并为弹出的id请求架子.有一次我从响应$.get()或$.post()取其我喜欢用我,然后在回调中调用递归函数.
这是代码中的详细说明:
// array of shelf IDs
var shelves = new Array(1,2,3,4);
// the recursive function
function getShelfRecursive() {
// terminate if array exhausted
if (shelves.length === 0)
return;
// pop top value
var id = shelves[0];
shelves.shift();
// ajax request
$.get('/get/shelf/' + id, function(){
// call completed - so start next request
getShelfRecursive();
});
}
// fires off the first call
getShelfRecursive();
Run Code Online (Sandbox Code Playgroud)
小智 8
我使用这个非常简单的代码来保持ajax调用彼此"超越".
var dopostqueue = $({});
function doPost(string, callback)
{
dopostqueue.queue(function()
{
$.ajax(
{
type: 'POST',
url: 'thephpfile.php',
datatype: 'json',
data: string,
success:function(result)
{
dopostqueue.dequeue();
callback(JSON.parse(result));
}
})
});
}
Run Code Online (Sandbox Code Playgroud)
如果您不希望队列自行处理,您可以dequeue从函数中删除它并从另一个函数中调用它.至于获取队列长度,对于这个例子,它将是:
dopostqueue.queue().length
Run Code Online (Sandbox Code Playgroud)
小智 7
我发现上述解决方案有点复杂,而且我需要在发送之前更改请求(更新新数据令牌).
所以我把这个放在一起.资料来源:https://gist.github.com/2470554
/*
Allows for ajax requests to be run synchronously in a queue
Usage::
var queue = new $.AjaxQueue();
queue.add({
url: 'url',
complete: function() {
console.log('ajax completed');
},
_run: function(req) {
//special pre-processor to alter the request just before it is finally executed in the queue
req.url = 'changed_url'
}
});
*/
$.AjaxQueue = function() {
this.reqs = [];
this.requesting = false;
};
$.AjaxQueue.prototype = {
add: function(req) {
this.reqs.push(req);
this.next();
},
next: function() {
if (this.reqs.length == 0)
return;
if (this.requesting == true)
return;
var req = this.reqs.splice(0, 1)[0];
var complete = req.complete;
var self = this;
if (req._run)
req._run(req);
req.complete = function() {
if (complete)
complete.apply(this, arguments);
self.requesting = false;
self.next();
}
this.requesting = true;
$.ajax(req);
}
};
Run Code Online (Sandbox Code Playgroud)
小智 7
我需要为未知数量的ajax调用执行此操作.答案是将每个推入一个数组,然后使用:
$.when.apply($, arrayOfDeferreds).done(function () {
alert("All done");
});
Run Code Online (Sandbox Code Playgroud)
小智 7
你可以扩展jQuery:
(function($) {
// 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)
然后使用它像:
$.ajaxQueue({
url: 'doThisFirst.php',
async: true,
success: function (data) {
//success handler
},
error: function (jqXHR,textStatus,errorThrown) {
//error Handler
}
});
$.ajaxQueue({
url: 'doThisSecond.php',
async: true,
success: function (data) {
//success handler
},
error: function (jqXHR,textStatus,errorThrown) {
//error Handler
}
});
Run Code Online (Sandbox Code Playgroud)
当然你可以使用任何其他$ .ajax选项,如type,data,contentType,DataType,因为我们正在扩展$ .ajax
jAndy 答案的另一个版本,没有计时器。
var ajaxManager = {
requests: [],
addReq: function(opt) {
this.requests.push(opt);
if (this.requests.length == 1) {
this.run();
}
},
removeReq: function(opt) {
if($.inArray(opt, requests) > -1)
this.requests.splice($.inArray(opt, requests), 1);
},
run: function() {
// original complete callback
oricomplete = this.requests[0].complete;
// override complete callback
var ajxmgr = this;
ajxmgr.requests[0].complete = function() {
if (typeof oricomplete === 'function')
oricomplete();
ajxmgr.requests.shift();
if (ajxmgr.requests.length > 0) {
ajxmgr.run();
}
};
$.ajax(this.requests[0]);
},
stop: function() {
this.requests = [];
},
}
Run Code Online (Sandbox Code Playgroud)
使用:
$(function() {
$("a.button").click(function(){
ajaxManager.addReq({
type: 'POST',
url: 'whatever.html',
data: params,
success: function(data){
// do stuff
}
});
});
});
Run Code Online (Sandbox Code Playgroud)