感谢您的阅读。
我有一个输入字段,它将XMLHttpRequest中的内容发送到php脚本。该脚本使用字段中的POST数据查询数据库并返回结果。
因为使用onkeyup调用XMLHttpRequest,所以输入一个冗长的值会在短时间内发送多个调用。为了解决这个问题,我编写了一些代码,用于创建时间戳,将其加载到会话中,休眠,然后重新检查时间戳。如果时间戳增加,则意味着后续调用并且脚本应该中止。否则脚本将执行。这是代码。
$micro = microtime(true);
$_SESSION['micro'] = $micro;
usleep(500000); // half a second
if ($micro < floatval($_SESSION['micro']))
{
// later call has been made, abort
echo 'abort';
exit;
}
else
{
// okay to execute
}
代码似乎首先按预期工作。如果我在输入字段中添加或删除一个或两个字符,结果会很快显示。
但是,如果我尽可能快地输入一个好的12个字符,那么会有很长的延迟,有时会延迟2到3秒。
我正在使用localhost,因此没有连接问题。查询也很小,抓取一个包含特定行中单个单词的列。
我还将XMLHttpRequest设置为异步,因此也应该没问题。
xmlhttp.open("POST","/test/",true);
如果我删除防洪代码,输入该字段会立即返回结果 - 无论我输入多少和多快。
这几乎就像usleep()不断堆叠自己或其他东西。
我自己想出了这个代码,我能做到最好。不知道为什么它的表现不如预期。
非常感谢帮助,谢谢!
答案 0 :(得分:3)
当您使用session_start()
打开会话时,PHP会锁定会话文件,以便在另一个请求打开时对相同会话的任何后续请求将被阻止,直到会话关闭(您完全正确使用&# 34;堆积&#34;你怀疑发生了这种情况。)
您可以致电session_write_close()
关闭会话并解除锁定,但在这种情况下这可能不会有所帮助。
每次按下按键时发生的事情,发出请求并在前一个请求完成时备份每个请求,一旦会话被释放,其他一个请求将打开会话并休眠,并且这种情况一直持续到他们都完成了。
相反,我在Javascript中创建一个全局变量,指示请求是否正在进行中。如果是,则不要发送另一个请求。
这样的事情:
<script>
var requesting = false;
$('#input').on('keyup', function() {
if (requesting) return ;
requesting = true;
$.ajax({
url: "/url"
}).done(function() {
requesting = false;
});
}
</script>
答案 1 :(得分:0)
drew010的答案完美地解释了我的问题(谢谢!)。但是他们的代码示例,从我收集到的解释方式(我没有尝试过),与我需要的相反。如果用户键入“hello”,h将被发送,但ello可能不会,除非结果使其及时返回。 (对不起,如果这是一个错误的假设)
这是我自己提出的解决方案。
<input type="text" onkeyup="textget(this.value)" />
<script>
var patience;
function ajax(query)
{
// XMLHttpRequest etc
}
function textget(input)
{
clearTimeout(patience);
patience = setTimeout(function(){ajax(input)},500);
}
</script>
当在输入字段中按下某个键时,它会将其当前值传递给textget函数。
textget函数清除现有的计时器(如果有)并启动一个新计时器。
当计时器完成倒计时时,它会将值进一步传递给ajax函数以执行XMLHttpRequest。
因为每次调用textget函数时都会重置计时器,如果在计时器结束前(0.5秒)进行了新的调用,则前一个调用将丢失并被新的调用替换。
希望这有助于某人。