我需要使用有限的流来创建顺序异步ajax请求。截至目前,我被允许在Web服务器上只占用一个流,因此我只能在时间上执行一个ajax请求。
我有以下功能,当我被允许一次只使用一个流时,它可以帮助我。
function initiateChain() {
var i = 0;
var tasks = arguments;
var callback = function () {
i += 1;
if (i != tasks.length) {
tasks[i](callback); //block should call callback when done otherwise loop stops
}
}
if (tasks.length != 0) {
tasks[0](callback); //initiate first one
}
}
说我是否有三个ajax辅助函数
function getGadgets(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
function getBooks(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
function getDeals(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
以下调用可确保从此客户端发出不超过1个ajax请求
initiateChain(getGadgets, getBooks, getDeals);
现在我需要增强initiateChain以支持任意数量的流。假设我可以使用2或n个数据流,我想知道这样做,而无需更改ajax辅助函数getGadgets,getDeals,getDeals。
简而言之,我有一组函数N,在这种情况下,getGadgets,getDeals和getDeals(| N | = 3)都需要连接到Web服务器。目前,我一次只能执行一个请求,因此initiateChain函数按顺序调用这三个方法。如果我有权访问M连接,我想执行| N |并行功能(最多M个)。
答案 0 :(得分:15)
如果您正在使用jQuery,那么您可以使用其.queue方法对您的ajax调用进行排队,然后按顺序执行它们。要运行多个序列,可以将初始出列包装在循环中。
function add_api_call_to_queue(qname, api_url) {
$(document).queue(qname, function() {
$.ajax({
type : 'GET',
async : true,
url : api_url,
dataType : 'json',
success : function(data, textStatus, jqXHR) {
// activate the next ajax call when this one finishes
$(document).dequeue(qname);
}
});
});
}
$(document).ready(function() {
var queue_name = 'a_queue';
var concurrent_calls = 2;
// add first AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/books');
// add second AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/dvds');
// add third AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/shoes');
// start the AJAX queue
for (i=0;i<concurrent_calls;i++) {
$(document).dequeue(queue_name);
}
})
答案 1 :(得分:1)
只要您的回调都是同步的,这应该适合您,如果没有让您走上正确的轨道
var initiateChain = function () {
var args = arguments,
index = 0,
length = args.length,
process = function ( index ) {
if ( index < length ) {
$.ajax({
url: '/example.php',
complete: function () {
// Callbacks get run here
args[ index ];
process( ++index );
}
});
}
};
if ( length ) {
process( 0 );
}
};
initiateChain( getGadgets, getDeals, getDeals );
答案 2 :(得分:0)
谢谢@James,我从你编辑的长度中得到了线索。因此,调用是异步ajax请求。因此,我们的想法是创建M个异步调用 upfront 。然后,当每一个完成时,他们将继续那么多。
我确实尝试过nodejs,然后关注initiateChain按预期工作
var calls = [];
function initiateChain() {
var i = 0;
var maxSteams = 2;
var tasks = arguments;
var callback = function () {
i += 1;
if (i < tasks.length) {
tasks[i](callback); //block should call callback when done otherwise loop stops
}
}
if (tasks.length) {
i = ((tasks.length > maxSteams) ? maxSteams : tasks.length) - 1;
for (var j = 0; j < maxSteams; j+=1) {
if (j < tasks.length) {
tasks[j](callback); //initiate first set
} else {
break;
}
}
}
}
//test methods
for(var k = 0; k < 8; k+=1 ) {
calls[k] = (function (message, index) {
return function (callback) {
var ts = new Date().getTime();
console.log(message + " started - " + ts);
setTimeout(function() {
ts = new Date().getTime();
console.log(message + " completed - " + ts);
callback();
}, index * 1000);
};
})("call" + (k+1), (k+1))
}
initiateChain(calls[0], calls[1], calls[2], calls[3],
calls[4], calls[5], calls[6], calls[7]);
在我的实验中,我得到了以下结果
call1 started - 1360580377905
call2 started - 1360580377926
call1 completed - 1360580378937
call3 started - 1360580378937
call2 completed - 1360580379937
call4 started - 1360580379937
call3 completed - 1360580381945
call5 started - 1360580381945
call4 completed - 1360580383946
call6 started - 1360580383946
call5 completed - 1360580386959
call7 started - 1360580386959
call6 completed - 1360580389950
call8 started - 1360580389950
call7 completed - 1360580393972
call8 completed - 1360580397959