首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在可杀死的“线程”中运行JS;检测和取消长期运行的进程。

在可杀死的“线程”中运行JS;检测和取消长期运行的进程。
EN

Stack Overflow用户
提问于 2014-02-22 15:15:36
回答 1查看 356关注 0票数 2

汇总:如何执行JavaScript函数,但如果它没有以一个时间框架(例如2秒)结束,那么如何“执行”(杀死)它?

详细信息

我正在为交互式编写和测试PEG语法编写一个web应用程序。不幸的是,我使用聚乙二醇解析的JavaScript库有“臭虫”,其中某些写得不好或未完成的语法会导致无限的执行(某些浏览器甚至没有检测到)。你可以愉快地打字,在你的语法上工作,突然浏览器锁上了,你失去了所有的辛苦工作。

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

代码语言:javascript
运行
复制
grammarTextarea.onchange = generateParserAndThenParseInputAndThenUpdateThePage;

我想把它改为:

代码语言:javascript
运行
复制
grammarTextarea.onchange = function(){
  var result = runTimeLimited( generateParserAndThenParseInput, 2000 );
  if (result) updateThePage();
};

我已经考虑过使用iframe或其他选项卡/窗口来执行内容,但即使是这个混乱的解决方案不能保证在最新版本的主要浏览器中工作。。然而,我很高兴接受一个只适用于Safari、Chrome和Firefox最新版本的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-23 01:45:06

Web工作者提供这种功能--只要长期运行的函数不需要访问窗口或文档或闭包--尽管有点麻烦。以下是我最后得到的解决方案:

main.js

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21956169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档