(我看过所有类似的问题/答案,但没有一个能解决我的问题。)
代码:
var timeoutHandle;
function showLoader(show) {
if (show) {
$('.loader').html('Loading...');
$('.loader').show();
timeoutHandle = setTimeout(function () {
if ($('.loader').is(':visible')) {
$('.loader').html('Still loading...');
}
}, 15000);
}
else {
$('.loader').hide();
clearTimeout(timeoutHandle);
}
}
AJAX函数在调用服务器之前只调用showLoader(true)
,然后在结果之后调用showLoader(false)
。我有时会在15秒之前看到文本从“正在加载...”更改为“仍然加载...”,因此就好像计时器线程仍在运行一样。上面的代码有什么问题吗?或者问题可能与其他代码有关..
编辑:我必须补充一点,showLoader(true)
可以在来自服务器的响应之前再次(再次)调用
答案 0 :(得分:19)
在创建新帐号之前,您应该先添加一项检查,看看是否已有timeoutHandle
。
试试这个:
if(timeoutHandle){
clearTimeout(timeoutHandle);
timeoutHandle = null;
}
timeoutHandle = setTimeout(function () {
if ($('.loader').is(':visible')) {
$('.loader').html('Still loading...');
}
}, 15000);
然后在else情况下将timeoutHandle
设置为null,然后清除它:
clearTimeout(timeoutHandle);
timeoutHandle = null;
如果多次调用showLoader(true)
函数,这将消除您创建并发超时的可能性。
答案 1 :(得分:3)
可能发生的情况是,您要拨打showLoader
多个电话,因为这是一个全局功能,您可以从任何地方访问它,您通常不希望这样。
我会考虑将其更改为 monad 实现:
function create_loader(elem) {
var handle = null;
function show() {
elem.html('Loading...');
elem.show();
if (handle !== null) {
clearTimeout(handle); // clear the previous one
}
handle = setTimeout(function () {
elem.html('Still loading...');
}, 15000);
}
return {
show: show,
clear: function () {
elem.hide();
clearTimeout(handle);
handle = null;
}
};
}
用法:
var loader = create_loader($(".loader"));
loader.clear();
loader.show();
loader.show(); // each new call to show will reset the 15s timer
loader.show();
loader.show();
loader.clear();
// and you can make another one that operates independently of other one
var another_loader = create_loader($(".anotherLoader"));
现在你有一个loader
对象知道它自己的状态。
答案 2 :(得分:1)
在你的帖子中你提到showloader可以在第一次返回之前多次调用。这是你的问题。您正在使用新的timeoutHandle覆盖已存在的timeoutHandle,而不会破坏现有的句柄。在创建新的timeoutHandle之前,应检查是否设置了timeoutHandle。
答案 3 :(得分:0)
如果存在timeoutHandle,则不要调用 clearTimeout(timeoutHandle)然后启动新请求