【发布时间】:2014-12-30 16:22:32
【问题描述】:
从我对 setTimeout() 和 setInterval() 的研究来看,这似乎应该可以工作,但它会在停止等待的时候中断,并且控制台会输出一条错误消息。
我设置了一个页面来执行一些服务器端和客户端性能测试,然后执行 ajax 调用将测试结果保存到数据库中。它工作得很好,但最近我添加了一个浏览器测试(基于谷歌的 Octane 代码)。我想要做的是让 jQuery 等到 Octane 完成并产生最终分数并用该分数填充一个 div 之后,然后执行 ajax 调用以保存所有测试结果。我尝试在递归函数中使用 setTimeout() 来做到这一点,但代码在 saveData() ajax 调用之前就失败了。 Octane 将运行,该函数将按应有的方式运行,并每 5 秒继续调用一次,然后 Octane 完成并且该函数调用 saveData(),这就是它中断的地方。
这是基本的代码结构:
...Octane code
...<div id="finalScore" style="display:none;">When Octane is done, it will change display of this div to block and populate it with test score</div>
<script>
$(document).ready(function() {
//set some vars
var waitCounter = 0;
var request = $.ajax({//this is a test of download time
url: path to a text file
type: "GET",
success: function(result) {
//crunch some numbers
var requestUpload = $.ajax({//only want to do upload test if download was successful
url: //path to a file
type: 'POST',
data: formData,
processData: false,
contentType: false,
mimeType: 'multipart/form-data',
cache: false,
success: function(data) {
//crunch some numbers
waitForClientScore();//new function, replaces saveData() below
//saveData(nDLSpeedMbps, nULSpeedMbps, nLoopSpeedMbps, nQuerySpeedMbps, nReadSpeedMbps, nWriteSpeedMbps, nAvgLoop, nAvgQuery, nAvgRead, nAvgWrite);
}
});
requestUpload.fail(function(xhr, status) {
//handle upload fail
});
}
});
request.fail(function( jqXHR, textStatus ) {
//handle download fail
});
function clientScoreReady() {//is Octane done yet?
var clientScoreDiv = document.getElementById('finalScore');
var divDisplayValue = clientScoreDiv.style.display;
return (divDisplayValue == "block");
}
function waitForClientScore() {
if (clientScoreReady()) {
clearTimeout(t);
saveData(nDLSpeedMbps, nULSpeedMbps, nLoopSpeedMbps, nQuerySpeedMbps, nReadSpeedMbps, nWriteSpeedMbps, nAvgLoop, nAvgQuery, nAvgRead, nAvgWrite);
}
else if (waitCounter >= 12) {//make 12 recursive calls max (60 sec)
clearTimeout(t);
console.log("timed out after 12 recursive calls");
}
else {//recursive function call
waitCounter = waitCounter + 1;
console.log(waitCounter);
t = setTimeout(waitForClientScore, 5000);
}
}
function saveData(nDLSpeedMbps, nULSpeedMbps, nLoopSpeedMbps, nQuerySpeedMbps, nReadSpeedMbps, nWriteSpeedMbps, nAvgLoop, nAvgQuery, nAvgRead, nAvgWrite){
//put all argument values into userdata struct
$.ajax({
url : path to page that saves userdata to DB
type: "POST",
data : userdata,
success: function(data, textStatus, jqXHR) {
//handle success
},
error: function (jqXHR, textStatus, errorThrown) {
//handle fail
}
});
}
});
</script>
当我执行页面并观察控制台时会发生这种情况:Octane 正在运行,而 waitForClientScore() 函数发现 Octane 没有完成,因此它成功地递增 waitCounter 并在 5 秒内调用自身。然后当 Octane 完成后,Octane 填充 div 并将其显示从无更改为阻塞。 WaitForClientScore() 看到显示是块,并调用 saveData()。然后 saveData() 内部的 ajax 调用失败——控制台输出一条消息“$ 未定义”。
saveData()(已注释掉)在移动到 waitForClientScore() 内部之前工作正常。
我尝试将 waitForClientScore() 放在上传成功函数中,但同样的事情发生了,来自控制台的错误消息不同。 waitForClientScore() 一直调用自己,直到 Octane 完成,但随后控制台输出一条消息,指出 waitForClientScore() 不是一个函数。
【问题讨论】:
-
你能粘贴错误信息吗?同样在 chrome 中转到 Inspect element-> Network Tab 然后搜索最后一个 ajax 请求。单击它,然后查看响应选项卡和请求选项卡,看看是否有任何返回的错误可能对您有所帮助。
-
也有可能您的客户端 JavaScript 控制台中不会出现 MySql 错误。
-
Uncaught ReferenceError: $ is not defined 它引用了 saveData() 的 "$.ajax" 行中的 $
-
你尝试过 jQuery.ajax 吗?你也可以试试 console.log(jQuery(body));这可能是因为 jQuery 在您当前的范围内不可用。