在重复的 jQuery / Ajax 函数中设置延迟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18965768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set a delay in a repeating jQuery / Ajax function
提问by Jeroen
I am trying to add a delay to a repeatable query.
我正在尝试为可重复查询添加延迟。
I found out that .delay is not the one to use here. Instead, I should go with setInterval or setTimeout. I tried both, without any luck.
我发现 .delay 不是在这里使用的那个。相反,我应该使用 setInterval 或 setTimeout。我两个都试过,没有任何运气。
Here's my code:
这是我的代码:
<?php
include("includes/dbconf.php");
$strSQL = mysql_query("SELECT workerID FROM workers ORDER BY workerID ASC");
while($row = mysql_fetch_assoc($strSQL)) {
?>
<script id="source" language="javascript" type="text/javascript">
$(setInterval(function ()
{
$.ajax({
cache: false,
url: 'ajax2.php',
data: "workerID=<?=$row['workerID'];?>",
dataType: 'json',
success: function(data)
{
var id = data[0]; //get id
var vname = data[1]; //get name
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
});
}),800);
</script>
<?php
}
?>
<div id="output"></div>
The code works fine, it outputs the result as asked. It's just loads without the delay. The timout and / or interval doesn't seem to work.
代码工作正常,它按要求输出结果。它只是加载而没有延迟。超时和/或间隔似乎不起作用。
Anybody knows what I am doing wrong?
有谁知道我做错了什么?
回答by Chris Kempen
I've never understood why people always add their AJAX requests in intervals rather than letting the successful AJAX calls just call themselves, all the while risking severe server load through multiple requests and not just making another call once you had a successful one come back.
我一直不明白为什么人们总是每隔一段时间添加他们的 AJAX 请求,而不是让成功的 AJAX 调用只调用自己,同时通过多个请求冒着严重的服务器负载风险,而不是在成功调用后再次调用。
In this light, I like to write solutions where the AJAX calls just call themselves on completion, something like:
有鉴于此,我喜欢编写 AJAX 调用仅在完成时调用自己的解决方案,例如:
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
$.ajax({
// ajax parameters here...
// ...
success: function() {
setTimeout(callAjax, my_delay);
}
});
}
I hope this makes sense! :)
我希望这是有道理的!:)
Update:
更新:
After reviewing this again, it's been brought to my attention that there was also a problem in the PHP code in the original question that I needed to clarify and address.
再次查看后,我注意到原始问题中的 PHP 代码中也存在一个问题,我需要澄清和解决。
Although the script above will work great in creating a delay between AJAX calls, when added to the PHP code in the original post the script will just be echo
'd out as many times as the number of rows the SQL query selects, creating multiple functions with the same name and possibly making all AJAX calls simultaneously...not very cool at all...
虽然上面的脚本在创建 AJAX 调用之间的延迟方面效果很好,但是当添加到原始帖子中的 PHP 代码时,脚本将被echo
删除与 SQL 查询选择的行数一样多的次数,从而创建多个函数同名,可能同时进行所有 AJAX 调用……一点也不酷……
With that in mind, I propose the following additional solution - create an array
with the PHP script that may be digested by the JavaScript one element at a time to achieve the desired result. First, the PHP to build the JavaScript array string...
考虑到这一点,我提出了以下额外的解决方案 -array
使用 PHP 脚本创建一个可以被 JavaScript 一次一个元素消化的脚本,以实现所需的结果。一、PHP构建JavaScript数组字符串...
<?php
include("includes/configuratie.php");
$strSQL = mysql_query("SELECT workerID FROM tWorkers ORDER BY workerID ASC");
// build the array for the JavaScript, needs to be a string...
$javascript_array = '[';
$delimiter = '';
while($row = mysql_fetch_assoc($strSQL))
{
$javascript_array .= $delimiter . '"'. $row['workerID'] .'"'; // with quotes
$delimiter = ',';
}
$javascript_array .= ']';
// should create an array string, something like:
// ["1","2","3"]
?>
Next, the JavaScript to digest and process the array we just created...
接下来,JavaScript 来消化和处理我们刚刚创建的数组……
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// add your JavaScript array here too...
var my_row_ids = <?php echo $javascript_array; ?>;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
// check to see if there are id's remaining...
if (my_row_ids.length > 0)
{
// get the next id, and remove it from the array...
var next_id = my_row_ids[0];
my_row_ids.shift();
$.ajax({
cache : false,
url : 'ajax2.php',
data : "workerID=" + next_id, // next ID here!
dataType : 'json',
success : function(data) {
// do necessary things here...
// call your AJAX function again, with delay...
setTimeout(callAjax, my_delay);
}
});
}
}
回答by cssyphus
Note: Chris Kempen's answer (above) is better. Please use that one.He uses this techniqueinside the AJAX routine. See this answerfor why using setTimeout is preferable over setInterval.
注意:Chris Kempen 的回答(以上)更好。请使用那个。他在 AJAX 例程中使用了这种技术。请参阅此答案以了解为什么使用 setTimeout 优于 setInterval。
//Global var
is_expired = 0;
$(function (){
var timer = setInterval(doAjax, 800);
//At some point in future, you may wish to stop this repeating command, thus:
if (is_expired > 0) {
clearInterval(timer);
}
}); //END document.ready
function doAjax() {
$.ajax({
cache: false,
url: 'ajax2.php',
data: "workerID=<?=$row['workerID'];?>",
dataType: 'json',
success: function(data) {
var id = data[0]; //get id
var vname = data[1]; //get name
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
}); //END ajax code block
} //END fn doAjax()
回答by vsync
I've devised a a wrapper methodwhich adds a custom delay on-topof the default $.ajax
method. This is a way to have (on alljQuery ajax calls) a delay, throughout your entire app.
我设计了一个包装方法,它在默认方法的基础上添加了一个自定义延迟$.ajax
。这是一种在整个应用程序中(在所有jQuery ajax 调用上)延迟的方法。
Very handy in simulating real-life random latency.
在模拟现实生活中的随机延迟时非常方便。
(function(){
$._ajaxDelayBk = $.ajax; // save reference to the "real" ajax method
// override the method with a wrapper
$.ajax = function(){
var def = new $.Deferred(),
delay = typeof $.ajax.delay == 'undefined' ? 500 : $.ajax.delay,
delayTimeout,
args = arguments[0];
// set simulated delay (random) duration
delayTimeout = setTimeout(function(){
$._ajaxDelayBk(args)
.always(def.resolve)
.done(def.resolve)
.fail(def.reject)
}, delay);
def.abort = function(){
clearTimeout(delayTimeout);
};
return def;
}
})();
USE EXAMPLE:
使用示例:
// optional: set a random delay to all `ajax` calls (between 1s-5s)
$.ajax.delay = Math.floor(Math.random() * 5000) + 1000;
var myAjax = $.ajax({url:'http://whatever.com/API/1', timeout:5000})
.done(function(){ console.log('done', arguments) })
.fail(function(){ console.log('fail', arguments) })
.always(function(){ console.log('always', arguments) })
// Can abort the ajax call
// myAjax.abort();