在Javascript中队列Ajax请求?

时间:2012-06-29 14:22:48

标签: javascript ajax

我想每秒执行一次Ajax请求。我的下一个代码完美无缺。

    window.onload = function () {
        setTimeout(doStuff, 1000); //wait before continuing
    }

    function doStuff() {
        $.ajax({
            // ...
        });
        setTimeout(doStuff, 1000);
    };

但是此时如果我使用像Fiddler这样的工具阻止我的请求,系统会继续发送新的Ajax请求。我想排队他们,并在我的服务器的答案后发送我的下一个Ajax请求。我怎么能这样做?

5 个答案:

答案 0 :(得分:2)

在成功回调中调用setTimeout:

function doStuff() {
    $.ajax({
        // ...
        success: function(result) {
            // ...
            setTimeout(doStuff, 1000);
        }
    });
}

答案 1 :(得分:1)

我遇到了类似的问题并解决了,所以我想我会在SO上分享我的答案。

这是我做的:

// Global vars:

var ajaxQue = [];   //array containing immediate que of ajax object request to be fired off
var ajaxCache = {}; //object holding ajax requests. 
var ajaxThreadActive = 0;   //var for indicating if the ajaxQue if currently firing off or not. 



//get the last (newest) ajax Request
function getLastRequest() {
    for (i in ajaxCache) {
        ajaxQue.push(ajaxCache[i]);
        delete ajaxCache[i];
        return; //aim to only get one request at a time inorder to catch more requests
    }
    //if no items in the cache exist, will come here
    ajaxThreadActive = 0; //ajax queue is now empty
}

//put an ajax request in an obj with a specific id so that if a newer ajax request is created before the ajax requests are finished sending, it will replace the old one
function queRequest(ajaxObj, id) {
    if (arguments.length != 2) {    //id argument is optional
        id = uuid++;    //create unique id as default
    }
    if (id in ajaxCache) {
        console.log('duplicate request');   
    }
    ajaxCache[id] = ajaxObj;
    if (ajaxThreadActive == 0) {
        ajaxThreadActive = 1;
        getLastRequest();   //retrieve most 'updated' ajax request
        fireOffAjaxQue();   
    } else {
        return 'ajax thread is running';
    }
}


//fire off the ajax queue
function fireOffAjaxQue () {
    if ((ajaxQue.length > 0) && ajaxThreadActive == 1) {    //an if check on the thread active incase I want to close this from another place in code
        $.ajax(ajaxQue[0]).always( function () {
            setTimeout(function () {
                getLastRequest();   //retrieve most 'updated' ajax request
                fireOffAjaxQue();
            }, 50); //fire off another ajax request since this one has been completed.
        });
        ajaxQue.shift();    //perform this immediately after the ajax request is sent, will execute before the .always() function
    } 
}

用法很简单,而不是你通常在jQuery中做的事情:

$.ajax({url: 'someplace.php',
        data: dataVar,
        success: function(data) {...});

改变它:

//create ajax object
var ajaxObj = {url: 'someplace.php',
               data: dataVar,
               success: function (data) {...}};
 //send ajax object to que

然后将其发送到Que:

 queRequest(ajaxObj);  //send to que without an id since this is a unique request
 // *******OR********
 queRequest(ajaxObj, id);   //send to the que with an id IF this is to replace any 'older' requests of the same id

我已经包含了一个AjaxCache来保存最新的 ajax请求。即如果你有一个函数在用户的击键上发送重复的请求,有时你只需要发送最新的,最新的请求(如表单信息)。在创建此管理器的方式中,它处理具有关联ID的请求(可选),以便新请求可以通过使用相同的id覆盖请求来替换旧请求。

//for an example, I use it like this in my webpage
queRequest(ajaxObj, 'table1Data'); 

现在,如果队列仍在触发我使用'table1Data'发出的任何请求,则只会覆盖标识为'table1Data'的ajaxObj,因此只会发送最少量的Ajax请求。

答案 2 :(得分:0)

使用async使ajax请求等到第一次完成

jQuery.ajax({
    url: "query.php?Time="+myTimestamp(),
    async: false,
    success: function(data){
        jQuery.ajax({
            url: "query.php?Time="+myTimestamp(), 
            async: false,
            success: function(data){

            }
        });
    }
});

答案 3 :(得分:0)

我已将http://code.google.com/p/jquery-ajaxq/用于生产应用程序。

我已经定制了代码来中止运行ajax请求。

  • 导航Ajax(导航到屏幕) - 使用中止。

  • 数据提交 - 使用的队列。可以有不同的名称不同的队列。

答案 4 :(得分:0)

只需在请求的成功处理程序中移动下一个请求的触发器:

function doStuff() {
    $.ajax({
        // ...
        success: function( data ) {
           // your other code
           setTimeout(doStuff, 1000);
        }
    });  
};