PHP,jQuery& Ajax调用乱序

时间:2011-06-09 15:25:47

标签: php javascript jquery ajax

我正在使用jQuery进行Ajax调用...我有大量的Ajax调用附加到div。这些Ajax加载请求是由PHP foreach循环生成的......问题是它们是按顺序呈现的;它们被设置在数组......

<script type="text/javascript">
function loadPage(target, url, append)
{
    if (append == true) {
        $.get(url, function(data) { $(target).append(data) });
    }
    else {
        $(target).load(url);
    }
    return false;
}
</script>

////// ----- PHP

<?php
    $this->data['sidebar']  = array('login', 'active_leagues', 'latest_forum_threads', 'latest_matches', 'sponsors');

    if (isset($sidebar[0]) && !empty($sidebar[0]))
    {
        echo '<div class="right_col">';
        foreach($sidebar as $val)
        {
            echo "<script>loadPage('.right_col', 'http://dev.banelingnest.com/sidebar/". $val ."', true)</script>";
        }
        echo '</div>';
    }

我很想知道这是因为Web服务器对某些请求的响应速度比其他人慢...除此之外,我不知道为什么会发生这种情况。您有什么想法我可以按顺序保留请求吗?

7 个答案:

答案 0 :(得分:6)

您必须在请求之前创建参考点,并将结果附加到它们:

var counter = 0;

function loadPage(target,url,append)
{
    if (append == true) {
        var id = "container_"+counter;
        $(target).append("<div id='"+id+"'></div>")
        $.get(url, function(data) { 
            $("#"+id).append(data);
        });
        counter++;
    } else {
        $(target).load(url);
    }

    return false;
}

您的参考元素将在每次loadPage()次调用时附加到目标,因此它们将按照正确的顺序排列,并且请求可以按任意顺序排列,它们将在正确的位置加载。

答案 1 :(得分:3)

这种情况正在发生,因为ajax调用是异步的,它们发出的顺序与它们返回的顺序无关。它们都将独立发生,并且有些人希望比其他人跑得更快。

您需要使用$ .ajax而不是$ .get,并将async设置为false。

请参阅此问题:How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

您还可以使用@inti提供的独特而有趣的解决方案。

答案 2 :(得分:1)

您可以执行同步请求而不是异步请求,这会强制浏览器等到每个请求完成后再开始下一个请求。对于任何“冗长”请求(或许多短请求)的缺点,浏览器将被锁定。

您可能希望调查在单个AJAX调用中发送所有请求,而不是每次调用一次请求。这样,双方的脚本都很容易保持一切顺序。否则,您将被卡住,具体取决于服务器的用户链接,错误率低,延迟低,拥塞率低。

所以不要做相当于

loadPage(1); // fetch data #1
loadPage(37); // fetch data #37
loadPage(203); // fetch data #203

做类似

的事情
loadPage([1,37,203]); // fetch all 3 at once.

答案 3 :(得分:1)

我有两个可能有用的想法,第一个是:

jQuery有一个$(document).ready(function()函数,它可能是从父函数调用的,或者是以某种方式继承的,这意味着JavaScript在PHP的其余部分加载之前不会运行。

我已经看到一些函数在没有声明的情况下从jQuery继承它。

第二个是: 我假设此功能在页面中或在页面的早期运行,而不是文档中的脚或更高版本。

我希望他们有所帮助。

答案 4 :(得分:0)

这是AJAX的本质,是的,服务器对某些人的响应速度比其他人快。

如果你想要它们,你必须先进行第一次呼叫,然后在complete事件中呼叫下一个呼叫,依此类推;本质上是创建一个同步的调用链(与AJAX中的 A 相反)。

如果不知道你想要它们的具体原因,这可能比它的价值要多得多。

无论如何,它会消除用户体验,因为如果一个呼叫很慢,所有其他呼叫都必须等待。

答案 5 :(得分:0)

最简单的解决方案是创建占位符,如inti所述。您的元素不一定按顺序显示,但它们最终会以正确的顺序排列。如果您需要它们也按顺序显示,则使用deferreds

是一个简单的队列
var queue = [];
function loadPage(target,url) {
    queue.push($.get(url));
    $.when.call($, queue).then(function() {
        $(target).append(Array.prototype.pop.call(arguments));
    });
}

AJAX调用将并行运行,但回调将严格按顺序触发。

答案 6 :(得分:0)

以下是我需要按顺序加载的数组或网址所做的事情。 我首先创建了包装器的顺序,而不是ajax调用,并将结果加载到匹配的包装器中。这使调用保持异步,但您仍然是正确的顺序。

$.fn.dashboarder = function(options) 
{
    var settings = $.extend({ 
        urls:        [],
    }, options || {});

    var self = this;

    if (settings.urls.length) 
    {
        $(self).html('');
        /// create wrapper blocks in the proper order, so they eventually display in this order
        $(settings.urls).each(function( index, value ) 
        {
            var wrapper = $( "<div />" )
                .addClass('dashboard-block-item')
                .attr('id', 'dashboard-block-item-'+index);
            $(self).append($(wrapper));
        });

        $(settings.urls).each(function( index, value ) 
        {
            $('#dashboard-block-item-'+index).load(value, function( response, status, xhr ) 
            {
            }).delay(5000 * index);
        });

    }

    return this;
}

function debug( obj ) {
    if ( window.console && window.console.log ) {
        window.console.log( obj );
    }
};