简体   繁体   English

队列AJAX调用

[英]Queue AJAX calls

Hello I am doing a Horizontal scrolling website like: http://vanityclaire.com/ 您好我正在做一个横向滚动网站,如: http//vanityclaire.com/

However, rather than having one large HTML file, after the load of the homepage, I am ajaxing in the children of home, using jQuery .load(). 然而,在主页加载之后,我使用jQuery .load()在家里的孩子们中,而不是拥有一个大的HTML文件。

At present I for-each div and ajax in ithe url that sits in the title. 目前我为每个div和ajax in the url位于标题中。 But the AJAX returns out of order, and as I add more pages don't fancy spanging the server with 30+ http:// requests. 但是AJAX返回乱序,并且当我添加更多页面时,不要想用30多个http://请求对服务器进行操作。

How do I synchronously do the AJAX calls, ie wait for the first to comeback before a request another, or even send two at a time. 我如何同步执行AJAX调用,即在请求之前等待第一个回复,或者甚至一次发送两个。

I have been scouring, and cannot figure out what I need. 我一直在淘,也无法弄清楚我需要什么。

This is my HTML: 这是我的HTML:

<div id="mainLayout" class="fullwidth scrollArea">
    <div class="scrollItems">
      <div id="page-1" class="scrollItem" title="/">
        <div>HOME PAGE CONTENT</div>
      </div>
      <div id="page-2" class="scrollItem" title="/Page2.html">
        <div class="loading"> </div>
      </div>
      <div id="page-3" class="scrollItem" title="/Page3.html">
        <div class="loading"> </div>
      </div>

      <div id="page-4" class="scrollItem" title="/Page4.html">
        <div class="loading"> </div>
      </div>
      <div id="page-5" class="scrollItem" title="/Page5.html">
        <div class="loading"> </div>
      </div>
    </div>
  </div>

And my JS: 我的JS:

function s_loadingInitialPages() {
    var loadingItems = new Array();
    $(".scrollArea .scrollItem").each(function () {
        if ($(this).attr('title') != '/') {
            var oDelem = $(this);
            loadingItems.push(oDelem);
            //alert('test');
        }
    });

    for (i = 0; i < loadingItems.length; i++) {
        // title attribute is the URL to get
        var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent=';
        $(loadingItems[i]).load(ajaxURL);

    }
}

Is there a plugin I can just keep adding functions to a queue, and let that handle it? 是否有插件我可以继续向队列添加功能,让它处理它?

The trick is to use the callbacks. 诀窍是使用回调。 You make one ajax call and on its success callback you make the next one. 你进行一次ajax调用,并在成功回调时创建下一个调用。

To do this just add them all to a queue and have a wrapper around it that sends them one by one. 要做到这一点,只需将它们全部添加到队列中并在其周围放置一个包装器,逐个发送它们。

I wrote one a few days ago. 我几天前写了一篇。 I'll show you an implementation in a second. 我将在一秒钟内向您展示一个实现。

// Buffer class. Has a public append method that expects some kind of Task.
// Constructor expects a handler which is a method that takes a ajax task
// and a callback. Buffer expects the handler to deal with the ajax and run
// the callback when it's finished
function Buffer(handler) {
    var queue = [];

    function run() {
        var callback = function () {
             // when the handler says it's finished (i.e. runs the callback)
             // We check for more tasks in the queue and if there are any we run again
             if (queue.length > 0) {
                  run();
             }
        }
        // give the first item in the queue & the callback to the handler
        handler(queue.shift(), callback);
    } 

    // push the task to the queue. If the queue was empty before the task was pushed
    // we run the task.
    this.append = function(task) {
        queue.push(task);
        if (queue.length === 1) {
            run();
        }
    }

}

// small Task containing item & url & optional callback
function Task(item, url, callback) {
    this.item = item;
    this.url = url;
    this.callback = callback
}

// small handler that loads the task.url into the task.item and calls the callback 
// when its finished
function taskHandler(task, callback) {
    $(task.item).load(task.url, function() {
        // call an option callback from the task
        if (task.callback) task.callback();
        // call the buffer callback.
        callback();
    });
}

// create a buffer object with a taskhandler
var buffer = new Buffer(taskHandler);

for (i = 0; i < loadingItems.length; i++) {
    // title attribute is the URL to get
    var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent=';
    buffer.append(new Task(loadingItems[i], ajaxURL));
}

Apologies for the wall of code. 为代码墙道歉。 Just implement your own Task and Handler. 只需实现自己的任务和处理程序。 The Buffer will work as long as the handler calls the second argument (the callback) when it's finished handling the task. 只要处理程序在完成处理任务时调用第二个参数(回调),缓冲区就会起作用。

Then just pass it a task and a handler. 然后只需传递一个任务和一个处理程序。 The handler does the ajax and calls the callback from the buffer when the ajax returns. 处理程序执行ajax并在ajax返回时从缓冲区调用回调。

For your specific example if what your loading takes a long time then this will take a long time to load all 30. The point of ajax is to have the server do stuff in parallel. 对于您的具体示例,如果您的加载需要很长时间,那么这将花费很长时间来加载所有30. ajax的目的是让服务器并行执行。

A far better solution in your case is to make 30 requests and then catch the results and make sure the results from your ajax calls are only appended to the dom in order. 在您的情况下,一个更好的解决方案是发出30个请求然后捕获结果并确保您的ajax调用的结果仅按顺序附加到dom。 This involves using $.ajax and adding keeping track of order somehow. 这涉及使用$ .ajax并以某种方式添加跟踪订单。

That way the server will do it as fast as it can and you can server it in order once you get it. 这样服务器就会尽可能快地完成它,一旦你得到它就可以按顺序服务它。 Alternatively if the things your doing are fast then queuing them in a buffer has no penalty. 或者,如果你做的事情很快,那么在缓冲区中排队它们就没有任何惩罚。

Most browsers can handle 6 or more simultaneous ajax requests to a single domain. 大多数浏览器可以同时处理对单个域的6个或更多个ajax请求。
http://www.browserscope.org/?category=network&v=top http://www.browserscope.org/?category=network&v=top

If your script places 30 ajax requests at once, the first 6 requests will go through very quickly. 如果您的脚本一次发出30个ajax请求,前6个请求将很快完成。 After that, the browser may start assigning arbitrary wait periods of up to 5 seconds. 之后,浏览器可能会开始分配长达5秒的任意等待时间。 Chrome is a prime example of this behavior. Chrome是此行为的主要示例。

Requests 1-6 return in 5 ms. 请求1-6在5毫秒内返回。

Requests 7-12 return in 5,005 ms. 请求7-12在5,005毫秒内返回。

Requests 11-18 return in 10,005 ms. 请求11-18在10,005毫秒内返回。

Requests 19-24 return in 15,005 ms. 请求19-24在15,005毫秒内返回。

Requests 25-30 return in 20,005 ms. 请求25-30在20,005毫秒内返回。

I recommend building a queue of function callbacks to handle all of your application's ajax requests and process no more than 6 of them at a time. 我建议构建一个函数回调队列来处理所有应用程序的ajax请求,并且一次处理不超过6个。

 var ajaxCownt = (ajaxCownt == null ? 0 : ajaxCownt); // Make limit globally accessible. var ajaxKue = (ajaxKue == null ? [] : ajaxKue); // Make queue globally accessible. function doMyAjaxRequest() { console.log("doing ajax request."); // Implement ajax request, here. } for (var i = 1;i <= 30;i++) { ajaxKue.push( function() { doMyAjaxRequest() } ); // Add request to queue. } while (ajaxCownt != null && ajaxCownt < 6 && ajaxKue != null && ajaxKue.length && ajaxKue.length > 0) { ajaxCownt++; console.log("incrementing pending ajax requests counter by 1."); ajaxKue.shift().call(); }; // Register an event to detect when an ajax request completes. // Allow for an additional ajax request to be processed. $( document ).ajaxComplete(function() { if (ajaxCownt && ajaxCownt > 0) { ajaxCownt--; console.log("decrementing pending ajax requests counter by 1."); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM