【问题标题】:This javascript setTimeout interacts with ajax requests in a really weird way这个 javascript setTimeout 以一种非常奇怪的方式与 ajax 请求交互
【发布时间】:2011-10-07 07:48:56
【问题描述】:

我正在编写这个脚本,以便它显示导入脚本的状态。它应该调用一个函数,每 X 秒运行一次 http 请求。

function progres_import() {
//if(import_status != 'finalizat') {
    alert("progres_import");
    setTimeout(function() { return update_progres_import(); }, 2000);
    setTimeout(function() { return update_progres_import(); }, 4000);
    setTimeout(function() { return update_progres_import(); }, 6000);
    setTimeout(function() { return update_progres_import(); }, 8000);

    //setTimeout(function() { progres_import(); }, 400);
//}
//else {

//}
}

这是我用来测试功能的。我把 cmets 也放进去只是为了展示我最终打算用它做什么。我尝试了所有可能的 setTimeout 调用,带引号、不带引号、带匿名函数和不带匿名函数。

var xmlhttp_import_progres;
function update_progres_import() {
xmlhttp_import_progres=GetXMLHttpObject();
if (xmlhttp_import_progres==null) {
    alert ("Browser does not support HTTP Request (xmlhttp_import_progres)");
    return;
}

var url="crm/ferestre/import_progres.php";  
url=url+"?sid="+Math.random();

xmlhttp_import_progres.onreadystatechange=function() {
    if (xmlhttp_import_progres.readyState == 4) {
        progres_resp = xmlhttp_import_progres.responseText;
        progres = progres_resp.split('_');
        import_nrc = progres[0];
        import_nrt = progres[1];
        import_status = progres[2];
        mesaj = 'Progres import: ' + import_nrc + ' / ' + import_nrt;
        //document.getElementById("corp_import_mesaj").innerHTML = mesaj;
        alert(progres_resp);        
    }
};
xmlhttp_import_progres.open("POST",url,true);
xmlhttp_import_progres.send(null);
}

这是 progres_import 函数的业务端。

发生的情况是我在导入过程开始时在第一个函数中获得了警报(“progress_import”),但第二个函数中的警报(progres_resp)仅在导入过程结束后才开始弹出(它仍然保持2 秒的间隔,所以从这个意义上说 setTimeouts 有效)。

ajax 请求中的 php 脚本只获取导入脚本设置的一些会话变量并打印出来以供 javascript 使用(x 导入 y 总计,z 失败,诸如此类)

知道为什么会这样吗?

【问题讨论】:

  • 能完整展示一下功能吗:update_progres_import?
  • 我的第一个想法是,服务器端,php脚本不能同时运行,如果是这样,那我们就完蛋了。
  • 你也能显示变量xmlhttp_import_progres吗?
  • 我猜你的问题是什么。但是您需要显示更多详细信息。
  • @vietean 刚刚粘贴了整个函数。

标签: javascript ajax settimeout


【解决方案1】:

xmlhttp_import_progres.readyState == 4) 只是请求末尾的true。因此,完成请求后会弹出警报对话框。

此外,您不能指望您的函数在 2 秒间隔后显示警报,因为服务器可能响应也可能不那么快。

最后一点:如果您想拥有定期更新功能,请使用setInterval(function(){...}, 2000)。

编辑

另外,以这种方式添加var:var xmlhttp_import_progres = GetXMLHttpObject();。目前,您正在全局定义 HTTP 对象,导致只能访问 HTTP 对象的一个​​实例。

【讨论】:

  • 我知道服务器可能响应不够快,但这就是为什么我给了它整整 2 秒的时间,基本上是单行回显。
  • 是的,但是考虑一下(服务器延迟):request A, 2 seconds, request B, 响应 A,响应 B 2 秒...
  • 我想要问的问题是“服务器可以在 ajax 请求中运行 php 脚本同时它正在执行导入吗?” (导入也是一个php脚本)
  • 不能在 JS 中直接从 PHP 中定义变量。您最好在发送请求之前显示通知 ("Sending..."),并在请求完成时显示结果。
  • 我会继续标记你的答案,但我的问题仍然存在:导入脚本似乎正在阻止 import_progress 脚本运行。这就是为什么它只在最后才开始显示警报。我对服务器端的东西不够精通,所以我什至不知道你是否可以同时运行两个脚本。感谢您的所有帮助。
【解决方案2】:

在这里,您可以尝试稍微编辑一下吗:
请考虑上面的答案,但是这段代码会让您清楚:


function progres_import() {
//if(import_status != 'finalizat') {
    alert("progres_import");
    setTimeout(function() { return update_progres_import(0); }, 2000);
    setTimeout(function() { return update_progres_import(1); }, 4000);
    setTimeout(function() { return update_progres_import(2); }, 6000);
    setTimeout(function() { return update_progres_import(3); }, 8000);

    //setTimeout(function() { progres_import(); }, 400);
//}
//else {

//}
}

与

var xmlhttp_import_progres = [];
function update_progres_import(i) {
    xmlhttp_import_progres[i]= GetXMLHttpObject();
    if (xmlhttp_import_progres[i]==null) {
        alert ("Browser does not support HTTP Request (xmlhttp_import_progres)");
        return;
    }

    var url="crm/ferestre/import_progres.php";  
    url=url+"?sid="+Math.random();

    xmlhttp_import_progres[i].onreadystatechange=function() {
        if (xmlhttp_import_progres[i].readyState == 4) {
            progres_resp = xmlhttp_import_progres[i].responseText;
            progres = progres_resp.split('_');
            import_nrc = progres[0];
            import_nrt = progres[1];
            import_status = progres[2];
            mesaj = 'Progres import: ' + import_nrc + ' / ' + import_nrt;
            //document.getElementById("corp_import_mesaj").innerHTML = mesaj;
            alert(progres_resp);        
        }
    };
    xmlhttp_import_progres[i].open("POST",url,true);
    xmlhttp_import_progres[i].send(null);
}

【讨论】:

    猜你喜欢
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2015-05-14
    • 2019-10-03
    相关资源
    最近更新 更多