创建Web Worker失败时是否可能捕获?

3
在下面的例子中,Web Worker的代码存在错误(未定义的引用),但是try {...} catch(e) {...} 并没有捕获到太多信息。消息“为什么我在这里?”出现在控制台上。
HTML文件:
<html>
<body>
<script type="text/javascript">

var worker;
try {
  worker = new Worker("foo.js");
  console.log('Why am I here ?');
} catch (e) {
  console.log('Error creating the worker.');
}
// No matter what, an object "worker" will created during the call to Worker()
// How to test that all went well
var worker_failed = false;
worker.addEventListener("error",
                        function(e) { worker_failed = true },
                        false);
// Is it correct to assume that "worker" is created asynchronously, and that checking
// that creation went well should not be sequential and the test below is not
// the way to do it ?
if ( worker_failed ) {
  // Worker("foo.js") failed, switch to plan B
}
</script>
</body>
</html>

网络工作者 (foo.js):


foobar = 2 + baz; // fails here (baz is undefined)
onmessage = function(e) {
  var data = e.data;
  postMessage(data);
};
1个回答

1

您可以异步处理工作线程中的错误。您需要监听工作线程的error事件。

worker.addEventListener("error", onError, false);

这里有一个关于Web Workers的很棒的教程here。您可以在handling errors部分找到您需要的内容。

您还可以查看官方的html5规范,以获取有关浏览器如何实现此功能的更多信息。


但是在工作线程创建之后,错误被捕获了。顺序如下:var worked = Worker('foo.js'); worker.addEventListener("error", onError, false); - lgautier
尽管尝试使用侦听器后,onError确实收到了错误信号,控制台也接收了错误信息。 - lgautier
如果你不希望错误显示在控制台上,你应该在worker中捕获它。正如规范中所述,“当工作线程的脚本发生未捕获的运行时错误时[...]用户代理必须将错误报告给包含该脚本的资源的URL”。Chrome调试器可能会以与你相同的方式监听error事件,并将信息传递给控制台。 - jbalsas
感谢您的回答和评论;我已编辑了问题。这有助于推理问题,并且这表明构造函数Worker()是异步的(并且代码条件光滑初始化在回调中)。我来到这里的原因是目前浏览器在Web Workers方面的状态非常不平衡(就Firefox 15.0而言,它对我来说最有效,尽管很容易崩溃)。 - lgautier
我认为你这里有一个概念错误。在创建工作者时没有错误。创建中的任何错误都将被 try{} catch{} 语句块捕获。你所遇到的是运行时错误。JS 是一种解释性语言,因此像你遇到的这种错误直到执行时才会被捕获。因此,当工作者被执行(在另一个线程中)时抛出错误。最后,根据规范,任何未捕获的错误都将使用 onError API 传递给父 URL。 - jbalsas
我现在意识到,我认为在调用Worker(“foo.js”)时对“foo.js”的评估是创建工作者以及该文件中的顶级组件作为工作者的方法和属性。但事实并非如此。它们局部于工作者,这一点必须与我头脑中的其他概念相结合。问题的起源是,在尝试使用其关联的Javascript代码创建一个Web Worker之前,我无法猜测浏览器是否实现了我需要的内容。类似测试if(window.Worker){worker = new Worker(“foo.js”)} else {<plan B>} - lgautier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接