如何设计一个长运行javascript的函数来避免得到浏览器警告"Unresponsive Script"
How to desgin a long running javascript function to avoid getting the browser warning "Unresponsive Script"
我有一个 JavaScript 函数,可以获取几百个(!)URL。
该函数必须按顺序提取这些 URL,因此在尝试下一次提取之前必须等待一次提取。
我该如何设计或如何调用此函数,以免收到浏览器警告“Unresponsive Script”?
注意:因为带有脚本的页面被很多用户使用,所以我无法更改特定于浏览器的设置(例如dom.max_script_run_time
)
运行 长异步脚本会阻止页面绘制。因此,您需要将您的任务转换为“批次”,并让浏览器在每个批次 运行 之后处理其他任务。
看看这个来自 https://javascript.info/event-loop 的例子:
let i = 0;
function count() {
// do a piece of the heavy job (*)
do {
i++;
progress.innerHTML = i;
} while (i % 1e3 != 0);
if (i < 1e7) {
setTimeout(count);
}
}
count();
现在繁重的任务是分批 1000
次迭代完成,而不是一批 1e7 次迭代。
在代码中我们说:
- 如果不是1000的倍数,则增加
i
。但是代码progress.innerHTML = i
在循环结束前不会更新界面。
- 一旦
i
乘以 1000,循环就会中断,另一个 batch
使用 setTimeout
被“推迟”并更新 UI。
您还可以将您的代码移动到 web worker 中,它 运行 在后台线程上运行并且不会干扰用户界面。
更新: 上面显示的 setTimeout
方法有效,但它不是一个完美的解决方案,因为:
JS 的主要脚本是 运行 在单线程上,异步操作不是 运行 在另一个线程上,它们只是被推迟到 运行 “稍后” .所以他们“总是”在 运行ning 时阻止主脚本,即使我们做了提到的 hack(当我们在做 - while 循环)。
如果我们想“真正”将繁重的任务与我们的主脚本分开,我们应该使用 Web Workers,它实际上是 运行 在另一个 OS 级别的线程上。
所以你最好的选择是使用 Web Worker 并使用 postMessage
系统传达结果。
注意:网络工作者无权访问 DOM
我有一个 JavaScript 函数,可以获取几百个(!)URL。
该函数必须按顺序提取这些 URL,因此在尝试下一次提取之前必须等待一次提取。
我该如何设计或如何调用此函数,以免收到浏览器警告“Unresponsive Script”?
注意:因为带有脚本的页面被很多用户使用,所以我无法更改特定于浏览器的设置(例如dom.max_script_run_time
)
运行 长异步脚本会阻止页面绘制。因此,您需要将您的任务转换为“批次”,并让浏览器在每个批次 运行 之后处理其他任务。
看看这个来自 https://javascript.info/event-loop 的例子:
let i = 0;
function count() {
// do a piece of the heavy job (*)
do {
i++;
progress.innerHTML = i;
} while (i % 1e3 != 0);
if (i < 1e7) {
setTimeout(count);
}
}
count();
现在繁重的任务是分批 1000
次迭代完成,而不是一批 1e7 次迭代。
在代码中我们说:
- 如果不是1000的倍数,则增加
i
。但是代码progress.innerHTML = i
在循环结束前不会更新界面。 - 一旦
i
乘以 1000,循环就会中断,另一个batch
使用setTimeout
被“推迟”并更新 UI。
您还可以将您的代码移动到 web worker 中,它 运行 在后台线程上运行并且不会干扰用户界面。
更新: 上面显示的 setTimeout
方法有效,但它不是一个完美的解决方案,因为:
JS 的主要脚本是 运行 在单线程上,异步操作不是 运行 在另一个线程上,它们只是被推迟到 运行 “稍后” .所以他们“总是”在 运行ning 时阻止主脚本,即使我们做了提到的 hack(当我们在做 - while 循环)。
如果我们想“真正”将繁重的任务与我们的主脚本分开,我们应该使用 Web Workers,它实际上是 运行 在另一个 OS 级别的线程上。
所以你最好的选择是使用 Web Worker 并使用 postMessage
系统传达结果。
注意:网络工作者无权访问 DOM