Php 而loop赢了';当我用JavaScript告诉它时,它不会结束
应该发生什么: 从PHP([html]和[next])中提取的JSON数组。如果[下一步]设置为0(当没有更多条目时)-while循环停止,应该是这样 发生了什么:Php 而loop赢了';当我用JavaScript告诉它时,它不会结束,php,javascript,jquery,ajax,json,Php,Javascript,Jquery,Ajax,Json,应该发生什么: 从PHP([html]和[next])中提取的JSON数组。如果[下一步]设置为0(当没有更多条目时)-while循环停止,应该是这样 发生了什么: 除了满足while()要求(因此当hasData设置为0时)之外,所有应该做的事情都会进入无限循环(它会一直请求最后一个条目,直到脚本变得“无响应”)ajax发送请求,并在有响应时执行回调。所以现在发生的是: 提出请求 发出另一个请求 发出另一个请求 发出另一个请求 因为它在一个while循环中。您正在用请求阻塞您的脚本,服务
除了满足while()要求(因此当hasData设置为0时)之外,所有应该做的事情都会进入无限循环(它会一直请求最后一个条目,直到脚本变得“无响应”)
ajax
发送请求,并在有响应时执行回调。所以现在发生的是:
- 提出请求
- 发出另一个请求
- 发出另一个请求
- 发出另一个请求
async:false
。然而,这总是让浏览器不负责任。最好的做法是使用async:true
,并在条件说明时触发另一个,但只有在得到响应后:
var hasData = '1';
while (hasData != 0) {
$.ajax({
url: '/ajax.php?updateRow='+hasData,
dataType: 'json',
async: false,
success: function(data) {
hasData = data.next;
$('.result').append(data.html);
}
});
正如Spycho所指出的,由于您正在获取JSON,一种更方便的方法可能是:
function check() {
$.ajax({
url: '/ajax.php?updateRow='+hasData,
dataType: 'json',
async: true,
success: function(data) {
hasData = data.next;
$('.result').append(data.html);
if(hasData != 0) check(); // do it again
}
});
}
check(); // fire the first request
AJAX中的第一个字母表示“异步”。浏览器不会在初始调用
$.ajax()
后等待响应,而是多次调用此函数
(function() {
var fireRequest = function() { // this function is not available anywhere else,
// to avoid having this process running more than once
$.getJSON('/ajax.php', {updateRow: hasData}, function(data) {
hasData = data.next;
$('.result').append(data.html);
if(hasData != 0) fireRequest(); // do it again
});
};
fireRequest(); // start the process
})(); // call it
此外,我建议您将您的响应数据转换为如下数字 hasData=data.next*1 有时候,即使JSON返回一个数字,javascript和比较也不会认为它是一个数字 hasData!=0
即使hasData=“0”…事实上,您的代码所做的事情离您自己的服务器上的拒绝服务攻击不远:) 正如其他人已经指出的那样,Ajax请求在完成之前不会阻塞。调用
$.ajax
会立即返回,实际请求在后台执行,并在完成后调用success
回调。这一切都意味着Javascript会以尽可能快的速度在中循环,因为没有任何东西能阻止它。这也意味着,当您的第一个请求试图完成时,Javascript可能产生了数千个新请求,所有这些请求都需要服务器处理
您的服务器将无法同时处理这么多请求,并且速度会变慢(如果您检查它的CPU和内存使用情况,您会注意到)。由于服务器速度减慢,Javascript将产生越来越多的请求。。。直到最后整个系统都停止运行,因为Javascript正在耗尽资源,而且您的服务器可能也在耗尽资源
在您的情况下,不建议使用while
循环。最好一次发送一个请求,并在success
回调中检查返回值。如果它还不是0,则生成另一个请求,并重复该过程
var hasData = 1;
function ajaxRequest() {
$.ajax({
//...
success: function(data) {
hasData = data.next;
$('.result').append(data.html);
if (hasData != 0)
{
ajaxRequest();
}
}
});
}
onCompleted
参数是一个回调函数,在更新过程完成后执行。您可以按如下方式使用它:
function updateRows(onCompleted) {
$.ajax({
url: '/ajax.php?updateRow='+hasData,
dataType: 'json',
success: function(data) {
hasData = data.next;
if (hasData == 0) {
return onCompleted();
}
$('.result').append(data.html);
updateRows(onCompleted); // not finished yet, recursion
}
});
}
由于已将async设置为false,浏览器将挂起,直到有响应可用。您的脚本可能没有陷入无限循环,它只是等待响应
检查服务器端脚本是否实际工作。Ajax请求是异步的!但是,如果设置了“async:false”,则不会。除非我们对这个名字过于迂腐,否则我们还应该告诉他使用XML……同步Ajax请求会让浏览器的UI在请求过程中没有响应。永远不要使用async:false
。这是一个很好的建议,但并不能真正解决问题(事实上,使上述代码异步会使问题变得更糟)。“async:false”应该可以阻止这种情况发生。@Grim浏览器的UI在非异步请求期间停止响应。从来没有这样做过,我没有,但OP做到了。在再次调用该函数之前,我也会尝试稍微延迟一段时间,这样如果没有任何结果,就不会影响带宽。@duri:同意,但OP设置了async:false
,所以这个答案很可能会误导他们。@grim,当我将async设置为true时-脚本崩溃了我的FF:),这不是异步的。但是你的其余答案是非常正确的。谢谢,我重新编写了这一部分。谢谢你的解释,帮助很大:)你可能想从使用$.ajax切换到[$.getJSON](),因为这样更整洁,并且会提出相同的请求。我想你的答案中有一个输入错误。您推荐了async:true
,然后在解决方案中编写了async:false
。@pimvdb:我只是好奇,您为什么使用参数。被调用方
而不是在递归示例中仅命名函数?@patrick dw:我认为这样会将函数放入全局对象中。我看事实并非如此(函数a(){})
不会将a
放入窗口中。a
不会想到这一点。命名它确实是一个更好的选择,谢谢。@pimvdb:不幸的是,在IE8和以下版本中确实如此,因为它们的命名函数表达式存在错误,但随后参数。被调用方将在“严格模式”中抛出类型错误+1表示递归解决方案。
updateRows(function() {
// Now all rows are updated
// Proceed with program flow
});