$.post 循环调用


$.post call from a loop

我有一个包含 9 个li元素的ul。我想在异步模式下通过 ajax 将一些信息加载到这些li元素中。

这很简单,不是吗?

我刚刚创建了一个for(i = 1; i<=9; i++)循环,并调用了$.post

失败:i将始终为 10,因为 for 循环运行得更快,然后是 $.post 。因此,让我们在网上搜索$.post in loop

我找到了三种解决方案。两个在这里,一个在这里。

所有这些都具有相同的效果:不异步工作。每次加载第一个,然后是第二个,然后是第三个等等......有时顺序在更改,但每个请求都在前一个请求完成时等待。

我正在使用 WIN 10 64 位、Apache 2.4 64 位、php 5.6 64 位。已经在 debian 盒子上尝试过了,效果是一样的。

在我的php文件中,有一个sleep(1)和一个echo 'a'

我的第一次尝试:

$('.chartContainer').each(function(index,obj) {
    var cnt = index + 1;
    $.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + cnt).data('time'), action: 'getChartByDateTime'}, function (reponse) {
        $(obj).html(reponse);
    });
});

我的第二次尝试:

for (var i = 1; i <= 9; i++) {
    (function (i) {
        var $obj = $('#chart_' + i);
        $.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
            $($obj).html(reponse);
        });
    })(i);
}

我的第三次尝试:

function loadResponse(i) {
    var $obj = $('#chart_' + i);
    $.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
        $($obj).html(reponse);
    });
}
$(function () {
    for (i = 1; i<=9; i++) {
        loadResponse(i);
    }
});

预期成果:

每 9 li在同一时间加载 1 秒。

有人可以引导我找到正确的解决方案吗?

编辑

也许我不清楚。在制作中,脚本将运行大约 3 秒。如果我发送一个请求来取回所有数据,那么响应到达时需要 9*3 = 27 秒。这就是为什么我想发送 9 个请求,并在 3 秒内取回所有数据。我认为这就是我们使用线程的原因。

我想要的是li在"相同"时间内获取所有的所有数据。不是一一的,也不是在一个请求中得到所有。

编辑 2

好吧,伙计们,为我感到羞耻,我想我误导了你们所有人。我的 php 脚本中有一个会话启动。

如果我删除所有内容,然后只是回声并在睡觉后死去。在这种情况下,5 个请求在 1 秒内响应,其他 4 个请求稍后响应。但我认为这是一个新的问题。

来自 jQuery 手册:

默认情况下,所有请求都是异步发送的(即默认情况下设置为 true)。如果需要同步请求,请将此选项设置为 false。跨域请求和数据类型:"jsonp"请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,在请求处于活动状态时禁用任何操作。

您确定您的浏览器未发送请求吗?您的 php 脚本可能不允许多个会话。您是否尝试过使用 firebug/chrome 检查器检查 ajax 调用?

编辑:

默认情况下,PHP 将其会话数据写入文件。当向启动会话 (session_start() 的 PHP 脚本发出请求时,此会话文件将被锁定。这意味着,如果您的网页向PHP脚本发出大量请求,例如,通过Ajax加载内容,则每个请求都可能锁定会话并阻止其他请求完成。

其他请求将挂起 session_start(),直到会话文件解锁。如果您的某个 Ajax 请求运行时间相对较长,则尤其糟糕。

可能的解决方案:

  1. 不要在不需要会话时使用会话
  2. 读取/写入必要信息后关闭会话:

    session_write_close(); 
    
  3. 例如,将您的会话存储在 Redis/mySQL 中
function loadResponse(i) {
    var $obj = $('#chart_' + i);
    $.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
        $($obj).html(reponse);
        if(i<=9) loadResponse(++i);
    });
}
var i = 1;
$(function () {
    loadResponse(i);
});

这里 loadResponse 函数是在页面加载时首次调用的。然后,在 POST 请求的响应上递归调用它。

你可以

试试这个。

for (var i = 1; i <= 9; i++) {
    var $obj = $('#chart_' + i);
    var time = $('#chart_' + i).data('time');
    (function ($obj, time) {
        $.post(getBaseUrl() + 'ajax.php', {dateTime: time, action: 'getChartByDateTime'}, function (reponse) {
            $obj.html(reponse);
        });
    })($obj, time);
}

尝试一次发送所有数据

var dateTime = [];
$('.chartContainer').each(function(index,obj) {
    var cnt = index + 1;
    dateTime.push({date:$('#chart_' + cnt).data('time'),el:'#chart_' + cnt});
});
 $.post(getBaseUrl() + 'ajax.php', {dateTime:dateTime , action: 'getChartByDateTime'}, function (reponse) {
       $.each(reponse,function(i,v){
          $(v.el).html(v.procesedData);
       });
    });

.php:

$ajaxresponse =[];
foreach($_POST['dateTime'] as $datetime) {
   $data = $datetime['date'];//change this with your results
   $ajaxresponse[]= array('procesedData'=>$data,'id'=>$datetime['id'])
}
return json_encode($ajaxresponse);