汇总:如何执行JavaScript函数,但如果它没有以一个时间框架(例如2秒)结束,那么如何“执行”(杀死)它?
详细信息
我正在为交互式编写和测试PEG语法编写一个web应用程序。不幸的是,我使用聚乙二醇解析的JavaScript库有“臭虫”,其中某些写得不好或未完成的语法会导致无限的执行(某些浏览器甚至没有检测到)。你可以愉快地打字,在你的语法上工作,突然浏览器锁上了,你失去了所有的辛苦工作。
现在,我的代码(非常简化):
grammarTextarea.onchange = generateParserAndThenParseInputAndThenUpdateThePage;我想把它改为:
grammarTextarea.onchange = function(){
var result = runTimeLimited( generateParserAndThenParseInput, 2000 );
if (result) updateThePage();
};我已经考虑过使用iframe或其他选项卡/窗口来执行内容,但即使是这个混乱的解决方案不能保证在最新版本的主要浏览器中工作。。然而,我很高兴接受一个只适用于Safari、Chrome和Firefox最新版本的解决方案。
发布于 2014-02-23 01:45:06
Web工作者提供这种功能--只要长期运行的函数不需要访问窗口或文档或闭包--尽管有点麻烦。以下是我最后得到的解决方案:
main.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);https://stackoverflow.com/questions/21956169
复制相似问题