【问题标题】:$.post call from a loop$.post 循环调用
【发布时间】:2016-03-17 09:42:48
【问题描述】:

我有一个带有 9 个 li 元素的 ul。我想在 asynch 模式下通过 ajax 向这些li 元素加载一些信息。

这很简单,不是吗?

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

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

我找到了三个解决方案。两个是here,一个是here

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

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

在我的 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 个稍后响应。但我认为这是一个新的话题。

【问题讨论】:

  • 为什么不将所有 9 个值发送到 php 脚本,处理它们并返回正确的结果?
  • 就像上面评论的那样,要走的路是只使用一次请求将所有相关数据发送到服务器一次
  • 好的,但这是我的问题。在生产中,脚本将运行大约。 3 秒。如果我发送一个请求,那么响应到达将需要 9*3 = 27 秒。这就是为什么我要发送 9 个请求,并在 3 秒内取回所有数据。
  • 我认为您的第二次尝试没有任何问题,除了变量名 =)。这里是jsfiddle.net/a5pacfjg,由于浏览器对同时请求的限制,它一次执行6个请求。
  • @Arno 提到的会话锁定问题。抱歉虚假信息。我以前从未遇到过这种情况。给我投反对票:)

标签: php jquery ajax


【解决方案1】:

来自 jQuery 手册:

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

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

编辑:

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

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

可能的解决方案:

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

    session_write_close(); 
    
  3. 例如将会话存储在 Redis/mySQL 中

【讨论】:

  • 这是评论而不是答案。无论如何,当页面加载时,所有的 ajax 都在网络检查器中。但是一个接一个地执行>vaso.hu/other/ajax/astroajax.jpg
  • 这看起来像请求正在等待前一个完成。你在 php 脚本中使用 session_start() 吗?
  • 是的,我愿意。对剧本有什么影响?
  • 简短版:PHP 打开一个带有会话信息的文件并锁定该文件。只要您不终止会话并且脚本未完成,具有相同会话 ID 的其他脚本将等待该脚本完成(释放锁定)。我将用更多信息编辑我的答案。
【解决方案2】:
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 请求的响应中递归调用它。

【讨论】:

  • 仅代码答案很少为 OP 提供太多见解/解释,请解释您做了什么/您的代码做了什么以及为什么/如何工作。
  • 没问题..!首先我在页面加载时调用了 loadresponse 函数,在得到 post 调用的响应后,我再次递归调用该函数。 (9次,因为我正在检查条件)。所以loadresponse会在得到之前调用的response后被调用...!!就是这样..
  • 请将其编辑为您的答案 :) 评论有被忽略/删除的风险。
  • 它不起作用,我它只加载 1。无论如何,我想同时取回所有 li 的所有数据,而不是一个。
  • 好的..刚刚检查了你的编辑..所以你可以做一件事..你可以在开始时隐藏li标签,当循环完成时你可以让它显示
【解决方案3】:

你可以试试这个。

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

【讨论】:

  • 仅代码答案很少为 OP 提供太多见解/解释,请解释您做了什么/您的代码做了什么以及为什么/如何工作。
  • 相同。一个一个加载。
【解决方案4】:

尝试一次发送所有数据

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);

【讨论】:

  • 你在 wordpress 和 ERP 上运行什么,为什么你的代码需要这么长时间才能执行?
  • 你在使用缓存吗?
猜你喜欢
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 2017-10-23
  • 2018-08-16
  • 2018-09-04
相关资源
最近更新 更多