【问题标题】:Does this JS Code work as expected?此 JS 代码是否按预期工作?
【发布时间】:2009-03-04 19:47:34
【问题描述】:

我每 3 秒发出一次 AJAX POST 请求以获取进程的状态。这很好用。

当进程达到 100% 时,将执行回调函数(如下所示)以向页面添加新元素,然后取消用于每 3 秒连续获取进度的 setTimeout 方法。但是,我的用户告诉我,它有时无法取消,并且新元素没有添加到页面中,而且我一直卡在显示“100%”。

我一次又一次地对此进行了测试,但它从来没有卡住过。代码看起来也不错,但是我的 JavaScript 技能不是很好,所以我希望有人能指出是否有可能发生这个问题?

我已经评论了代码,很抱歉它很长。我已经尝试减少它。

function convertNow(validURL){

    startTime = setTimeout('getStatus();', 6000); 
       //AJAX CALL TO RUN PROCESS
       $.ajax({
       type: "GET",
       url: "main.php",
       data: 'url=' + validURL + '&filename=' + fileNameTxt,
       success: function(msg){
       //ON SUCCESS CLEAR SETTIMEOUT AND SHOW ELEMENTS (text)
       clearTimeout(continueTime);
       clearTimeout(startTime);    
        $("#loading").hide("slow");
        $("#done").html("Done");   
       }//function

     });//ajax

}//function convertNow

function getStatus(){
        //AJAX CALL TO GET STATUS OF PROCESS
        $.ajax({
        type: "POST",
        url: "fileReader.php",
        data: 'textFile=' + fileNameTxt,
        success: function(respomse){
        textFileResponse = respomse.split(" ");
        $("#done").html("Processing...");
        }
        });//ajax
        clearTimeout(continueTime);

        if(textFileResponse[0]=='100.0%'){
            clearTimeout(continueTime);
        }
        else{
            clearTimeout(startTime);
            continueTime = setTimeout('getStatus();', 3000); 
        }
}

【问题讨论】:

  • "此 JS 代码是否按预期工作?" - 我想这取决于你的预期。
  • 它每次都非常适合我。只是一两个用户说它卡在“100%”并且没有显示“完成”元素。

标签: javascript settimeout


【解决方案1】:

在某些边缘情况下,textFileReponse[0]=='100.0%' 中可能存在解析错误,响应中的值不完全等于 100.0%(可能有额外的空格,或者可能存在一些细微差别一些平台等...)。这将导致代码进入 else {} 块,并且您的 getStatus 函数将再次排队。

编辑:鉴于 cmets 中的线程,两个 Ajax 代码块之间存在竞争条件的可能性也相同。 (只是为了读者的利益而把它放在这里)。结束编辑

但是,除了解析解析之外,您可能想要的是使用 setInterval(),只有一个计时器,而不是 startTime 和 continueTime 计时器。 setTimeout 只执行一次,而 setInterval 每 x 毫秒重复一次,所以你只需要一个。要取消 setInterval,请使用 clearInterval。

【讨论】:

  • 如果进入 else{} 块并且流程完成了那么流程成功函数应该是 clearTimeout(continueTime) 和 clearTimeout(startTime) 吧?!
  • 不一定... getStatus() 和 success() 是异步执行的,因此您最终可能会遇到竞争条件。鉴于您有成功检查,您可以摆脱 getStatus() 中的字符串检查。单独使用 getInterval() 成功区域可以取消间隔而不检查文本
  • 这也将清除竞争条件,假设这是问题
  • 我不能真正使用 setInterval,因为我有不同的秒数。 IE 也不能很好地使用 setInterval。我看不出 setInterval 将如何解决这个问题。我认为您对种族问题的看法是正确的,如何解决其他任何想法?
  • 好吧,伙计!好吧,这对 JS 来说有点不寻常,但是您可以尝试使用每个代码块在操作超时之前需要“获取”(松散地说)的锁变量。还是让 getStatus() 在开始时检查 #done 是否在继续之前包含“完成”?
猜你喜欢
  • 1970-01-01
  • 2011-10-28
  • 2013-10-20
  • 1970-01-01
  • 2012-01-17
  • 2015-12-12
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多