我有一个工作的ajax函数,调用时会显示当前时间,然后在显示新时间之前将setTimeout设置为10秒。当在文本输入上触发onkeyup时我调用此函数,它可以工作。但是有一个小问题。如果我在调用ajax函数后在文本输入中键入了其他内容,它将调用另一个ajax函数,并同时运行两个ajax函数。例如:
如果第一个ajax函数在触发时在3:00:00调用,而第二个ajax函数在3:00:05调用,则表示现在有两个ajax函数同时运行。第一个ajax函数将在10秒setTimeout之后的3:00:10再次触发,第二个ajax函数将在其10秒setTimeout之后的3:00:15再次触发。因此,在文本输入中触发onkeyup的次数越多,调用函数的次数就越多。我只想让自己的1个功能同时运行,而不是2,3或更多。我怎么做?谢谢。
ajax.php
<script type = "text/javascript">
function timeoutAjax(url,type,theName,id,timeout) {
$.ajax({
type: "POST",
url: url,
data: { select: $(type+'[name='+theName+']').val()},
error: function(xhr,status,error){alert(error);},
success:function(data) {
document.getElementById( id ).innerHTML = data;
setTimeout(function() { timeoutAjax(url,type,theName,id,timeout); }, timeout);
}
});
}
</script>
test1.php
<?php
include('ajax.php');
echo "<input type = 'text' name = 'name' onkeyup = 'timeoutAjax(\"test2.php\",\"input\",\"name\",\"output1\",\"10000\")'>";
echo "<div id = 'output1'/>";
?>
test2.php
<?php
$time = date('H:i:s A');
echo $time;
?>
************更多细节************
echo "<input type = 'submit' name = 'name1' value = 'Reset' onclick = 'timeoutAjax(\"test2.php\",\"input\",\"name1\",\"output1\",\"10000\")'>";
echo "<input type = 'submit' name = 'name2' value = 'Reset' onclick = 'timeoutAjax(\"test2.php\",\"input\",\"name2\",\"output2\",\"10000\")'>";
echo "<div id = 'output1'/>";
echo "<div id = 'output2'/>";
答案 0 :(得分:2)
如果我理解你的问题,你实际上是想在这里做两件事:
<强> 1。只有最后一次ajax调用
在最后一次击键后,做一些ajax调用。任何已经忙碌的ajax调用都可以跳过,你只对最后一个感兴趣。
这应该不是很难。调用ajax
函数时,jQuery返回一个xhr对象。在该xhr对象上,您只需调用abort()
方法即可取消挂起的呼叫。 (Abort Ajax requests using jQuery)
<强> 2。每x次重复ajax调用
现在你在ajax成功函数中设置一个timeout
,它将在给定时间后重复调用。问题是,当你再次从外部调用你的ajax函数时(所以不是递归地我的意思,而是通过另一个按键或其他东西)你将只创建另一个无限的ajax调用字符串。过了一会儿,你最终会有一大堆电话,这些电话会开始重叠并占用你所有的资源。
这可以通过将setTimeout的结果存储在变量中,并在每次设置新超时之前每次对该变量调用clearTimeout
来轻松解决。这样您就可以取消旧的队列&#39;然后开始一个新的。
英语很差,让我们试着通过更新你的代码来表明我的意思:
function timeoutAjax(url, type, theName, id, timeout, trigger) {
// abort pending calls
if (trigger.xhr) {
trigger.xhr.abort();
}
// abort queued calls
clearTimeout(trigger.queued);
// make the call
trigger.xhr = $.ajax({
type: "POST",
url: url,
data: {
select: $(type + '[name=' + theName + ']').val()
},
error: function (xhr, status, error) {
alert(error);
},
success: function (data) {
document.getElementById(id).innerHTML = data;
// queue a new call
trigger.queued = setTimeout(function () {
timeoutAjax(url, type, theName, id, timeout, trigger);
}, timeout);
}
});
}
再多一个旁注。即使我对您的代码所做的更改,您也会在每次击键时中止并进行新的ajax调用。并且中止ajax调用并不会自动意味着您的服务器停止处理请求,而是停止使用您正在使用的后端。对于你现在使用的简单php脚本,它可能很好,但是,在你第一次打电话之前,最好等到用户完成输入。这称为Debouncing,并不是很难实现:http://davidwalsh.name/javascript-debounce-function
答案 1 :(得分:0)
创建一个状态变量,用于跟踪ajax调用是否正在运行。最初将其设置为false。然后调用该函数时,检查状态;如果没有运行执行ajax调用,则将status var设置为true,然后在成功回调中再次将其设置为false:
<script type = "text/javascript">
//Create the status var (This may not be the best place to initialize it). Use your best judgement.
var running = false;
function timeoutAjax(url,type,theName,id,timeout) {
//Check if there is an ajax call in progress. If not execute one.
if(!running)
{
//Change the status to running
running = true;
console.log('In if')
console.log(running)
$.ajax({
type: "POST",
url: url,
data: { select: $(type+'[name='+theName+']').val()},
error: function(xhr,status,error){alert(error);},
success:function(data) {
document.getElementById( id ).innerHTML = data;
setTimeout(function() {
//Set the status to false for the inner function call
running = false;
timeoutAjax(url,type,theName,id,timeout);
//Set the status to true for the outer function call
runnng = true;
}, timeout);
}
});
}
}
</script>
触发第一个ajax调用和超时的外部函数只运行一次,但是,内部功能将连续每十秒运行一次。 我希望这适合你,如果是的话,请接受这个答案。感谢