Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.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
使用jQuery.Queue()对ajax请求进行排队_Jquery_Ajax_Queue - Fatal编程技术网

使用jQuery.Queue()对ajax请求进行排队

使用jQuery.Queue()对ajax请求进行排队,jquery,ajax,queue,Jquery,Ajax,Queue,我第一次使用jQuery.queue(),但还没有完全掌握它。 有人能指出我做错了什么吗 在firebug中,我仍然看到我的POST请求同时启动——因此我想知道我是否在错误的位置调用了dequeue() 还有-如何获取队列长度 我需要对这些请求排队的原因是,它会在单击按钮时被触发。用户可以快速连续单击多个按钮 试图删除我的代码的基本结构: $("a.button").click(function(){ $(this).doAjax(params); }); // method doAja

我第一次使用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");
       }
     });
   });

}

这里的问题是,
.ajax()
触发一个异步运行的ajax请求。这意味着,
.ajax()
立即返回,无阻塞。因此,您可以对函数进行排队,但它们几乎会像您描述的那样同时启动

我认为
.queue()
不是一个放置ajax请求的好地方,它更适合使用
fx方法。你需要一个简单的经理

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);
        }
     };
}());
这还远远不够完美,我只是想展示一下该怎么做。上面的例子可以这样使用

$(function() {
    ajaxManager.run(); 

    $("a.button").click(function(){
       ajaxManager.addReq({
           type: 'POST',
           url: 'whatever.html',
           data: params,
           success: function(data){
              // do stuff
           }
       });
    });
});

我发现上面的解决方案有点复杂,而且我需要在发送请求之前修改请求(以更新新的数据令牌)

所以我把这个放在一起。资料来源:


我需要做一件类似的事情,所以我想我应该在这里发布我的解决方案

基本上我得到的是一个页面,上面列出了书架上的项目,这些项目都有不同的标准。我想一个接一个地加载书架,而不是全部加载,以便更快地将一些内容发送给用户,让他们在加载其余内容的同时可以查看这些内容

基本上,我将每个工具架的ID存储在一个JS数组中,从PHP调用它们时使用该数组

然后,我创建了一个递归函数,每次调用它时,它都会从数组中弹出第一个索引,并为弹出的id请求shelf。一旦我从
$.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();

我还必须在我现有的解决方案中这样做,我发现我可以这样做:

//A variable for making sure to wait for multiple clicks before emptying.
var waitingTimeout; 

$("a.button").click(function(){
   $(this).doAjax(params);
   clearTimeout(waitingTimeout);
   waitingTimeout = setTimeout(function(){noMoreClicks();},1000);
});

// method
doAjax:function(params){ 

   $(document).queue("myQueueName", function(next){
     $.ajax({
       type: 'POST',
       url: 'whatever.html',
       data: params,
       contentType: "application/json; charset=utf-8",
       dataType: "json",
       success: function(data){
         doStuff;
         next();
       },
       failure: function(data){
         next();
       },
       error: function(data){
         next();
       }
     });
   });

}

function noMoreClicks(){
    $(document).dequeue("myQueueName");
}
通过使用队列函数中传递的
next()
回调,您可以将下一个操作出列。因此,通过将下一个放在ajax的处理程序中,可以有效地使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));
            }
        })
    });
}
在这个例子中,小提琴。单击按钮一次,然后等待一秒钟。您将看到超时触发并执行单个操作。下一步,尽可能快地(或快于1秒)单击按钮,您将看到每次单击按钮时,操作都在排队,只有等待一秒钟后,操作才会进入页面并一个接一个地淡入


这样做的好处是,如果队列已经清空,那么在清空时添加到队列中的任何操作都会放在末尾,然后在时机成熟时进行处理。

对于未知数量的ajax调用,我需要这样做。答案是将每一个都推入一个数组,然后使用:

$.when.apply($, arrayOfDeferreds).done(function () {
    alert("All done");
});

learn.jquery.com网站:

//jQuery在一个空对象上,我们将使用它作为队列
var ajaxQueue=$({});
$.ajaxQueue=函数(ajaxOpts){
//保留原始完整功能
var oldComplete=ajaxOpts.complete;
//对ajax请求进行排队
队列(函数(下一步){
//创建一个完整的回调来调用队列中的下一个事件
ajaxOpts.complete=函数(){
//调用原始的complete,如果它在那里的话
如果(已完成){
oldComplete.apply(这个,参数);
}
//运行队列中的下一个查询
next();
};
//运行查询
$.ajax(ajaxOpts);
});
};
//获取我们要复制的每个项目
$(“#项li”)。每个(功能(idx){
//将ajax请求排队
$.ajaxQueue({
url:“/ajax\u html\u echo/”,
数据:{
html:“[”+idx+“]”+$(this.html()
},
类型:“POST”,
成功:功能(数据){
//写入#输出
$(“#输出”)。追加($(“
  • ”{ html:数据 })); } }); });
  • 您可以扩展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);
    
    然后像这样使用它:

    $.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
        }       
    });
    

    当然,您可以使用任何其他$.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 = [];
        },
    }
    
    使用:

    $(function() {
        $("a.button").click(function(){
           ajaxManager.addReq({
               type: 'POST',
               url: 'whatever.html',
               data: params,
               success: function(data){
                  // do stuff
               }
           });
        });
    });
    

    这是我的解决方案,我使用它为一些浏览器游戏生成一个请求队列。 如果发生任何事情,我会停止这个队列,并完成一些特殊的最后请求或清理工作

    var get_array = ["first", "second", "third"];
    
    var worker = $("<div />"); // to line up requests in queue
    $.queuedAjax = function(args){  // add up requests for me       
        worker.queue(
            function(next){
                $.ajax(args).always(next);            
            }
        );
      };
    
    $.queuedSomething = function(){ // add up something special for me
        worker.queue(
            function(next){
                //worker.clearQueue();
                //worker = $("<div />"); //cleanup for next .each
                //maybe another .each           
            }
        );
      };
    
    $.each( get_array , function( key , value ) {
      $.queuedAjax({
        type: 'GET',
        url: '/some.php?get='+value,
        dataType: 'text',
        success: function(sourcecode){
    
            if (sourcecode.match(/stop your requests, idiot!/)) {   
                worker.clearQueue().queue($.queuedSomething);
                alert(' the server told me to stop. i stopped all but not the last ´$.queuedSomething()´ ');
            }
    
        }
      });           
    }); 
    $.queuedSomething();
    
    var get_数组=[“第一”、“第二”、“第三”];
    var worker=$(“”);//在队列中排列请求
    $.queuedAjax=函数(args){//为我添加请求
    工作队列(
    功能(下一个){
    $.ajax(args).always(next);
    }
    );
    };
    $.queuedSomething=function(){//为我添加一些特别的东西
    工作队列(
    功能(下一个){
    //worker.clearQueue();
    //worker=$(“”);//下一步的清理。每个
    //也许是另一个,每个
    }
    );
    };
    $.each(获取数组、函数(键、值){
    $.queuedAjax({
    键入:“GET”,
    url:'/some.php?get='+value,
    数据类型:“文本”,
    成功:函数(源代码){
    if(sourcecode.match(/停止你的请求,傻瓜!/){
    worker.clearQueue().queue($.queuedSomething);
    警报('服务器告诉我停止。我停止了所有,但没有停止最后一个´$.queuedSomething()');
    }
    }
    });           
    }); 
    $.queuedSomething();
    
    我使用这个非常简单的代码来防止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));
                }
            })
        });
    }
    
    如果不希望队列自行处理,可以从函数中删除
    dequeue
    ,然后从另一个函数调用它
    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));
                }
            })
        });
    }
    
    dopostqueue.queue().length
    
    /*
        Job Queue Runner (works with nodejs promises): Add functions that return a promise, set the number of allowed simultaneous threads, and then run
        (*) May need adaptation if used with jquery or angular promises
    
        Usage:
            var sourcesQueue = new QueueRunner('SourcesQueue');
            sourcesQueue.maxThreads = 1;
            childSources.forEach(function(source) {
                sourcesQueue.addJob(function() { 
                    // Job function - perform work on source
                });
            }
            sourcesQueue.run().then(function(){
                // Queue complete...
            });
    */
    var QueueRunner = (function () {
        function QueueRunner(id) {
            this.maxThreads = 1; // Number of allowed simultaneous threads
            this.jobQueue = [];
            this.threadCount = 0;
            this.jobQueueConsumer = null;
            this.jobsStarted = 0;
            if(typeof(id) !== 'undefined') {
                this.id = id;
            }
            else {
                this.id = 'QueueRunner';
            }
        }    
        QueueRunner.prototype.run = function () {
            var instance = this;        
            return new Promise(function(resolve, reject) {
                instance.jobQueueConsumer = setInterval(function() {
                    if(instance.threadCount < instance.maxThreads && instance.jobQueue.length > 0) {
                        instance.threadCount++;
                        instance.jobsStarted++;
                        // Remove the next job from the queue (index zero) and run it
                        var job = instance.jobQueue.splice(0, 1)[0];
                        logger.info(instance.id + ': Start job ' + instance.jobsStarted + ' of ' + (instance.jobQueue.length + instance.jobsStarted));
                        job().then(function(){
                            instance.threadCount--;
                        }, function(){
                            instance.threadCount--;
                        });
                    }
                    if(instance.threadCount < 1 && instance.jobQueue.length < 1) {
                        clearInterval(instance.jobQueueConsumer);
                        logger.info(instance.id + ': All jobs done.');
                        resolve();
                    }
                }, 20);
            });     
        };
        QueueRunner.prototype.addJob = function (func) {
            this.jobQueue.push(func);
        };
        return QueueRunner;
    }());
    
    var ajaxQueueMax = 5;
    self.ajaxQueue = ko.observableArray();
    self.ajaxQueueRunning = ko.observable(0);
    
    ko.computed(function () {
      if (self.ajaxQueue().length > 0 && self.ajaxQueueRunning() < ajaxQueueMax) {
        var next = self.ajaxQueue.shift();
        self.ajaxQueueRunning(self.ajaxQueueRunning() + 1);
        $.ajax(next).always(function () {
          self.ajaxQueueRunning(self.ajaxQueueRunning() - 1);
        });
      }
    });
    
    self.widgets = ko.observableArray();
    
    ko.computed(function () {
      var mapping = {
        create: function (options) {
          var res = ko.mapping.fromJS(options.data);
          res.count = ko.observable();
    
          // widget enrichment.
          self.ajaxQueue.push({
            dataType: "json",
            url: "/api/widgets/" + options.data.id + "/clicks",
            success: function (data) {
              res.count(data);
            }
          });
          return res;
        }
      };
    
      // Initial request for widgets
      $.getJSON("/api/widgets", function (data) {
        ko.mapping.fromJS(data, mapping, self.widgets);
      });
    });