JavaScript的setInterval可以阻止线程执行吗?
Can JavaScript's setInterval block thread execution?
setInterval 会导致页面中的其他脚本阻塞吗?
我正在开展一个项目,将Gmail相关的书签转换为Google Chrome扩展程序。书签使用 gmail greasemonkey API 与 gmail 页面进行交互。 API 的 JavaScript 对象是 Gmail 页面最后加载的部分之一,并通过 XMLHttpRequest 加载到页面中。 由于我需要访问此对象,并且全局 JavaScript 变量在扩展内容脚本中是隐藏的,因此我将一个脚本注入到 gmail 页面中,该脚本轮询变量的定义,然后访问它。 我正在使用 setInterval 函数进行轮询。这在大约 80% 的情况下有效。其余时间轮询函数会继续轮询,直到达到我设置的限制,并且永远不会在页面中定义 greasemonkey API 对象。
注入的脚本示例:
var attemptCount = 0;
var attemptLoad = function(callback) {
if (typeof(gmonkey) != "undefined"){
clearInterval(intervalId); // unregister this function for interval execution.
gmonkey.load('1.0', function (gmail) {
self.gmail = gmail;
if (callback) { callback(); }
});
}
else {
attemptCount ++;
console.log("Gmonkey not yet loaded: " + attemptCount );
if (attemptCount > 30) {
console.log("Could not fing Gmonkey in the gmail page after thirty seconds. Aborting");
clearInterval(intervalId); // unregister this function for interval execution.
};
}
};
var intervalId = setInterval(function(){attemptLoad(callback);}, 1000);
Javascript是单线程的(除了我们在这里不讨论的Web工作者)。 这意味着只要常规的 javascript 执行线程正在运行,您的setInterval()
计时器就不会运行,直到常规的 javascript 执行线程完成。
同样,如果您的setInterval()
处理程序正在执行,则在setInterval()
处理程序完成执行其当前调用之前,不会触发其他 javascript 事件处理程序。
因此,只要您的setInterval()
处理程序不会卡住并永远运行,它就不会阻止其他东西最终运行。 它可能会稍微延迟它们,但它们仍将在当前setInterval()
线程完成后立即运行。
在内部,javascript 引擎使用队列。 当某些内容想要运行(如事件处理程序或setInterval()
回调)并且某些内容已经在运行时,它会将事件插入队列中。 当当前的javascript线程完成执行时,JS引擎会检查事件队列,如果那里有什么东西,它会在那里选择最旧的事件并调用其事件处理程序。
以下是一些关于 Javascript 事件系统如何工作的其他参考:
JavaScript 如何在后台处理 AJAX 响应?
对 Javascript 方法的调用是线程安全的还是同步的?
我需要关注异步Javascript的竞争条件吗?
setInterval和setTimeout是"礼貌的",因为它们不会在你认为它们会触发的时候触发 - 它们会在线程清除时触发,在你指定的点之后。
因此,调度某些内容的行为不会阻止其他内容运行 - 它只是将自己设置为在当前队列的末尾运行,或在指定时间结束时运行(以较长者为准)。
两个重要的警告:
第一个是 setTimeout/setInterval 具有特定于浏览器的最小值。 通常,它们大约在 15 毫秒左右。 因此,如果您每 1ms 请求一次某些内容,浏览器实际上会将它们安排为每隔 browser_min_ms(不是真正的变量)。
第二个是,使用 setInterval,如果回调中的脚本花费的时间比间隔长,您可能会遇到火车残骸,浏览器将继续排队积压的间隔。
function doExpensiveOperation () {
var i = 0, l = 20000000;
for (; i < l; i++) {
doDOMStuffTheWrongWay(i);
}
}
setInterval(doExpensiveOperation, 10);
坏时代+=1;
但特别是对于你的代码,你正在做的事情本身并没有什么问题。就像我说的,setInterval 不会中止任何其他事情的发生,它只会将自己注入下一个可用的插槽中。
我可能会建议你使用 setTimeout,用于通用的东西,但你仍然做得很好,保持间隔的标签并保持间隔。
代码中的其他地方可能还有其他事情发生 - 要么在Google的交付中,要么在您的集合中。
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- javascript中的多线程
- Javascript支持多线程吗
- 如何在nodejs中创建线程池
- 起始节点.js用于并行的线程池
- Doppio:多线程是如何工作的,有什么限制吗
- 为什么Javascript SetTimeout()不是多线程的
- JavaScript的setInterval可以阻止线程执行吗?
- Do JS Reference Errors停止运行时线程执行
- 是否可以使用多线程执行Javascript函数
- jQuery-可以执行线程/异步操作吗
- 如何在nodejs的单独线程上执行dos命令
- Javascript引擎(或其他可嵌入语言),用于类似mongodb的查询执行环境和多线程
- 当类被多个元素使用时,在不同的线程中多次执行JavaScript代码
- 是Javascript中在单独线程中执行的事件循环
- 如何在Javascript中执行线程
- 在哪个线程上处理和执行AJAX请求等异步请求
- 是 promise.all 有用的,因为 javascript 是在单个线程中执行的
- dom事件——在JavaScript中有哪些方法可以重新获得对执行线程的控制?
- 在后台线程执行Javascript代码