当页面上存在其他setTimeout/setInterval调用时,setTimeout出现问题
Issue with setTimeout, when other setTimeout/setInterval calls are present on a page
我有一个通用的Javascript代码片段,所有客户都会将其添加到他们的网站中。这个代码片段获取了一个JS库,它有一些重要的函数,如果库被及时获取,就应该调用这些函数。如果没有及时获取库,则永远不应该调用这些函数。
为了实现这一点,我设置了一个超时,该超时有一个负责处理它的回调函数(它设置一个变量,取决于哪些重要函数将被调用或不被调用(。现在,它在大多数情况下都能完美工作,除非客户端的网站已经有一些定时器值很小的超时/间隔。请看小提琴http://jsfiddle.net/tmckM/37/,查看问题。
我需要找到一种通用的方法来实现这一点,这样,如果库被及时提取,那么在任何情况下都不会发生超时。
以下是JSFiddle 中使用的代码
//Though the library file is downloaded in time(which can be seen from network tab) but still the timeout fires before the library execution. I need to find a workaround for this issue
var library_timeout = 1000;
//All time values are in milliseconds
function loadLibrary() {
var b = document.createElement('script');
b.src = 'http://yourjavascript.com/35211527623/library.js';
b.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(b);
}
function wasteTime() {
if (!wasteTime.counter) {
wasteTime.counter = 1;
}
else {
wasteTime.counter++;
}
if (wasteTime.counter == 5) {
clearInterval(wasteTimerId);
}
console.warn('Start wasting time');
var initial = Date.now();
while (true) {
if (Date.now() - initial > 1000) {
break;
}
}
console.warn('Stopped wasting time');
}
function startProcess() {
window.process_started_at = Date.now();
console.log('Started the process at timestamp:', process_started_at);
setTimeout(function () {
window.lib_timeout_fired_at = Date.now();
console.log('Library timed out at timestamp:', lib_timeout_fired_at);
console.log('So, though the library file will still download, but the functions in it won''t be called.');
}, library_timeout);
loadLibrary();
}
//The following line is implemented on user's website.I can't change it.
wasteTimerId = setInterval(wasteTime, 0);//If this line is skipped then library is always executed first and then timeout occurs.
startProcess();
我在这里没有看到任何问题。lib加载时间可能不同,wasteTime
js加载可能不同,超时也可能不同。浏览器可以非常自由地首先执行加载的脚本,或者如果两者都已调度则触发超时。
解决方法是根本不使用超时。只需更改
if(window.lib_timeout_fired_at)
在你的库脚本中(你已经有了所有可用的变量(:
if (lib_started_at - process_started_at > library_timeout)
当然,您可能会重命名/加前缀,因此整体解决方案可能看起来像
window.lib_timeout_firing_at = Date.now() + 1000;
…
if (Date.now() > lib_timeout_firing_at)
相关文章:
- 如何在chrome扩展中存储数据/结果,以及如何使用setTimeout使其只被调用一次
- 在setTimeout中调用相同的函数
- 为什么setTimeout适用于无休止的递归调用
- settimeout调用的函数未结束
- 调用setTimeout内部的函数时发生引用错误
- setTimeout调用自身的任何问题
- 如何将参数传递给使用 setTimeout 调用的函数
- 使用 setTimeout 调用一次 forEach 的回调函数即可完成
- 从setTimeout调用window.event时失败
- 函数(从setTimeout调用)未返回值
- 与连续的setTimeout调用相比,setInterval更有可能按时发生
- setTimeout调用的顺序
- 在setTimeout调用期间超过的最大调用堆栈大小
- 使用setTimeout调用函数,并提供可选的停止方式
- 无用的setTimeout调用(参数周围缺少引号?)
- 为什么这个setTimeout()调用在控制台中工作,而不是作为一个油脂猴子脚本
- 为什么通过setTimeout调用原型函数时会丢失实例信息?
- 如何从匿名函数中对同一函数进行 setTimeout 调用
- 错误:无用的setTimeout调用(参数周围缺少引号?)
- 如何在 setTimeout 调用中解决超出范围的 Var