gpt4 book ai didi

javascript - 在可杀死的 'thread' 中运行 JS;检测和取消长时间运行的进程

转载 作者:行者123 更新时间:2023-11-27 23:59:44 24 4
gpt4 key购买 nike

总结:我如何执行一个 JavaScript 函数,但如果它没有在某个时间范围内(例如 2 秒)完成,则“执行”(终止)它?

详情

我正在为 interactively writing and testing PEG grammars 编写网络应用程序.不幸的是,我使用 PEG 进行解析的 JavaScript 库有 a 'bug'某些写得不好或未完成的语法导致无限执行(某些浏览器甚至检测不到)。你可以愉快地一起打字,研究语法,突然浏览器锁定,你失去了所有的努力。

现在我的代码是(非常简化):

grammarTextarea.onchange = generateParserAndThenParseInputAndThenUpdateThePage;

我想将其更改为:

grammarTextarea.onchange = function(){
var result = runTimeLimited( generateParserAndThenParseInput, 2000 );
if (result) updateThePage();
};

我考虑过使用 iframe 或其他选项卡/窗口来执行内容,但即使是这个困惑的解决方案 is not guaranteed to work in the latest versions of major browsers .不过,我很乐意接受仅适用于最新版本的 Safari、Chrome 和 Firefox 的解决方案。

最佳答案

Web worker 提供了这种能力——只要长时间运行的函数不需要访问窗口、文档或闭包——尽管是以一种有点麻烦的方式。这是我最终得到的解决方案:

ma​​in.js

var worker, activeMsgs, userTypingTimeout, deathRowTimer;
killWorker(); // Also creates the first one

grammarTextarea.onchange = grammarTextarea.oninput = function(){
// Wait until the user has not typed for 500ms before parsing
clearTimeout(userTypingTimeout);
userTypingTimeout = setTimeout(askWorkerToParse,500);
}

function askWorkerToParse(){
worker.postMessage({action:'parseInput',input:grammarTextarea.value});
activeMsgs++; // Another message is in flight
clearTimeout(deathRowTimer); // Restart the timer
deathRowTimer = setTimeout(killWorker,2000); // It must finish quickly
};

function killWorker(){
if (worker) worker.terminate(); // This kills the thread
worker = new Worker('worker.js') // Create a new worker thread
activeMsgs = 0; // No messages are pending on this new one
worker.addEventListener('message',handleWorkerResponse,false);
}

function handleWorkerResponse(evt){
// If this is the last message, it responded in time: it gets to live.
if (--activeMsgs==0) clearTimeout(deathRowTimer);
// **Process the evt.data.results from the worker**
},false);

worker.js

importScripts('utils.js') // Each worker is a blank slate; must load libs

self.addEventListener('message',function(evt){
var data = evt.data;
switch(data.action){
case 'parseInput':
// Actually do the work (which sometimes goes bad and locks up)
var parseResults = parse(data.input);

// Send the results back to the main thread.
self.postMessage({kind:'parse-results',results:parseResults});
break;
}
},false);

关于javascript - 在可杀死的 'thread' 中运行 JS;检测和取消长时间运行的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21956169/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com