Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用给定数量的流执行顺序异步ajax请求_Javascript_Ajax - Fatal编程技术网

Javascript 如何使用给定数量的流执行顺序异步ajax请求

Javascript 如何使用给定数量的流执行顺序异步ajax请求,javascript,ajax,Javascript,Ajax,我需要使用有限的流进行顺序异步ajax请求。到目前为止,我只允许占用web服务器上的一个流,所以一次只能执行一个ajax请求 当我一次只能使用一个流时,我有以下函数可以帮助我 function initiateChain() { var i = 0; var tasks = arguments; var callback = function () { i += 1; if (i != tasks.length) { tasks[i

我需要使用有限的流进行顺序异步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
 }
下面的调用确保从该客户端发出的ajax请求不超过1个

initiateChain(getGadgets, getBooks, getDeals);
现在我需要增强initiateChain以支持任意数量的流。假设我被允许使用2个或n个流,我想知道在不改变ajax助手函数getGadgets、getDeals、getDeals的情况下使用这些流的方法


简言之,我有一组函数N,在本例中是getgadget、getDeals和getDeals(|N |=3),每个函数都需要连接到web服务器。目前,我一次只能执行一个请求,因此initiateChain函数会依次调用这三个方法。如果我有权访问M个连接,我希望并行执行| N |个函数(最多M个)。

只要您的回调都是同步的,这应该对您有效,如果不是正确的话

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 );
var initiateChain=函数(){
var args=参数,
指数=0,
长度=args.length,
过程=功能(索引){
如果(索引<长度){
$.ajax({
url:“/example.php”,
完成:函数(){
//回调在这里运行
args[索引];
过程(++索引);
}
});
}
};
if(长度){
过程(0);
}
};
initiateChain(getGadgets、getDeals、getDeals);

谢谢@James,我从你编辑的长度中得到了线索。因此,这些调用是异步ajax请求。因此,我们的想法是在前端创建M个异步调用。然后,当每一个都完成时,他们将继续这许多

我用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]);

如果您使用的是jQuery,那么您可以使用它的方法对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);
    }

})
函数添加api调用到队列(qname,api url){
$(document).queue(qname,function(){
$.ajax({
键入:“GET”,
async:true,
url:api_url,
数据类型:“json”,
成功:函数(数据、文本状态、jqXHR){
//此调用完成后激活下一个ajax调用
$(文档).dequeue(qname);
}
});
});
}
$(文档).ready(函数(){
var queue_name='a_queue';
var并发_调用=2;
//将第一个AJAX调用添加到队列
将api调用添加到队列(队列名称,'/example/api/books');
//向队列添加第二个AJAX调用
将api调用添加到队列(队列名称,'/example/api/dvds');
//将第三个AJAX调用添加到队列
在队列(队列名称,'/example/api/shoes')中添加api调用;
//启动AJAX队列

对于(i=0;i您的问题到底是什么?正如我提到的,我有一组函数N,在本例中是getGadgets、getDeals和getDeals(|N |=3)每个都需要连接到web服务器。目前,我一次只能执行一个请求,因此initiateChain函数按顺序调用这三个方法。如果我可以访问M个连接,我希望并行执行| N |个函数(最多M个)。如果成功,您能将答案标记为获胜答案吗?谢谢这很聪明!非常感谢。队列函数不能用于异步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);
    }

})