使用Web Workers优雅地降级

时间:2009-07-22 13:46:28

标签: javascript multithreading web-worker

所以我开始越来越多地了解Web Workers。我认为这绝对是太棒了,但到目前为止我还没有看到任何人真正解决的问题是如何支持那些尚未支持新技术的旧浏览器。

到目前为止,我能够提出的唯一解决方案是围绕Web工作者功能制作某种包装,这可以归结为一些基于疯狂计时器的解决方案,可以模拟多线程执行。

但即使在这种情况下,如何检测Web worker是否是当前执行javascript的浏览器的受支持功能?

谢谢!

7 个答案:

答案 0 :(得分:11)

这是Web开发的一个古老问题:如何处理不支持您需要的浏览器。目前,我只提倡使用Web Workers来处理可能被分解的复杂,长时间运行的任务,并且出于某种原因,不能在服务器端完成。这样,如果您没有Web Workers,则只需等待更长时间。否则,你将不得不用包装器弄乱你的代码,以及你以后会试图避免的。我的降级策略会在页面加载后立即发生。

onload function伪代码:

if( window.Worker /*check for support*/ )
    someObject.myFunction = function() { /*algorithm that uses Web Workers*/ }
else
    someObject.myFunction = function() { /* sad face */ }

您仍然需要编写两次算法,但如果您想支持没有Web Workers的浏览器,则无论如何都必须这样做。所以这提出了一个有趣的问题:是否值得花时间(和金钱)两次写东西,这样对一些人来说可以更快一点?

答案 1 :(得分:4)

在咀嚼了几天之后,我最终在我的博客上写了一篇文章:
http://codecube.net/2009/07/cross-platform-javascript-webworker/

这个想法是,在没有定义WebWorker的情况下,有一个只使用内置技术的包装器API。虽然文章中的示例非常简单,但它确实适用于所有浏览器: - )

答案 2 :(得分:2)

Bespin项目(他们称之为)facade允许他们在Web Workers,Gears Workers中运行JavaScript代码,如果这些代码在主线程中不可用。

答案 3 :(得分:1)

这是John Resig所说的replying to a comment on his blog

  

我想到了这一点 - 但它会很棘手。您必须从一开始就使您的处理代码使用setTimeout / setInterval(此代码最终将在工作者和普通网站上工作)。因此,虽然对于支持工作者的浏览器,结果会稍微慢一点,但至少在两种情况下都可以。

答案 4 :(得分:0)

我遇到了一个有趣的问题,即没有Web Worker支持的任务在Firefox(无响应脚本)中太慢,但在所有其他现代浏览器中都足够快。 使用Web Workers,除了Opera(10.50)之外,它在除了Web Workers之外的所有浏览器中工作,但是没有它们,Opera工作得很好。

所以我编写了一个在可用时使用Web Worker API的WorkerFacade,或者通过对实际的Worker JS进行一些小的添加来伪造API。你可以找到WorkerFacade as a gist on GitHub。对我来说工作得很好,也可以帮助别人。

答案 5 :(得分:0)

您可以使用Modernizr(http://modernizr.com/download/#-webworkers)来检测浏览器是否支持网络工作者,此时您必须拥有两个版本......您可以在http://caniuse.com/webworkers

if(Modernizr.webworkers) 
{} 
else
{}

答案 6 :(得分:0)

@ geowa4

//globals
var useWorer={}
   ,noWorkerClosure=function(){...}
   ,myWorkerClosure=function(){...}
   ;
function init(){
         if(!!window.Worker){
           noWorkerClosure=null;
           useWorer=new myWorkerClosure();
         }
         else{
           useWorer=new noWorkerClosure();
           myWorkerClosure=null;
         }
}

通过这种方式,您可以释放一些内存,并且每次都不需要寻求支持。