我有一个页面,用于触发ajax请求,并在用户按下按钮后的前6秒显示加载符号:
<button onclick="runLoader();"></button>
<script>
var startTime=(new Date).getTime();
function runLoader(){
runAjax();
var i=0;
var timer = setInterval(function(e){
i++;
//code for loading sign
if(i==3)
clearInterval(timer);
} ,2000);
}
function runAjax(){
$.ajax({
//
}).done(function(){
var timer2 = setInterval(function(){
var d = new Date();
var t = d.getTime();
if(t-startTime>=6000){
clearInterval(timer2);
// do X
}
},500);
}
}
</script>
我希望仅在runLoader()
运行6秒且runAjax()
导致响应后立即采取行动 X 。
就像,如果runAjax()在2秒内响应,我仍然希望继续显示加载符号6秒,然后执行 X 。 如果加载符号显示6秒,我想等待runAjax()返回,只要它需要。
但使用Date()
方法会产生不准确的结果。例如:即使仅过了2秒,它也会显示7.765秒。我在某个地方阅读console.log(time)
以获得更高的准确性,但它在&lt; = IE9中无效。
有没有更好的方法来解决这个问题?
注意:我使用的是setInterval()
而不是setTimeout()
,因为加载涉及循环播放3个元素的数组,“提取”,“处理”和“加载”每个显示2秒:)
答案 0 :(得分:8)
function start(){
$.when(runLoader(), runAjax()).done(function() {
//both are now finished
});
}
function runLoader() {
//show loader here
var def = $.Deferred();
setTimeout(function() {
//hide loader here
def.resolve(true);
}, 6000);
return def.promise();
}
function runAjax() {
var def = $.Deferred();
$.ajax({...}).done(function(result) {
//handle response here
def.resolve(true);
});
return def.promise();
}
答案 1 :(得分:0)
我会设置一个标记,将其标记为“就绪”。可能有更好的方法来解决这个问题,但这只是我的头脑。
<script>
function runLoader(){
runAjax();
var i=0;
var timer = setInterval(function(e){
i++;
//code for loading sign
if(i==3)
clearInterval(timer);
} ,2000);
}
function runAjax(){
var timeElapsed = false;
setTimeout(function(){timeElapsed = true}, 6000);
$.ajax({
//
}).done(function(){
var timer2 = setInterval(function(){
if(timeElapsed){
clearInterval(timer2);
// do X
}
},500);
}
}
</script>
答案 2 :(得分:0)
您可以创建一个在runLoader()上运行的预调用函数和runAjax()的回调函数,它将验证其他操作是否完成,然后执行操作X.示例:
var ajaxDone = false;
var loaderDone = false;
function doActionX() {
//your action happens here
}
function tryToDoX() {
if (ajaxDone && loaderDone) {
doActionX();
}
}
function runLoader(){
loaderDone = false;
runAjax();
//show loading sign
setInterval(function(e){
//hide loading sign
clearInterval(timer);
loaderDone = true;
tryToDoX();
}, 6000);
}
function runAjax(){
ajaxDone = false;
$.ajax({
//whatever
}).done(function(){
ajaxDone = true;
tryToDoX();
}
}
没有必要进行重复超时并轮询这两种状态,因为它们只完成一次(在每次运行中,即在等待时,布尔值不设置为false和true)。
编辑:这种方法可以用于任何不会间歇性地改变状态的异步代码,即使没有jQuery也是如此。