2011-12-29 94 views
1

我给出了下面简化的JavaScript问题。面向对象的JavaScript锁

var PROJ=(function(){ 
    var tags={}, 
    var lock=true; 
    function onLoadComplete(){} 
    this.Tag = function(userConfig,callBack){  
      function loadConfig(){ 
        lock=false;    
        /* Do something privately having lock with me */ 
        lock=true; 
      }       
      this.load(){ 
        if(lock) loadConfig(); 
        else  setTimeout(load,1000); 
       // PROBLEM is this(above) load is calling OUTER load..! 
      } 
     return this; 
    }; 

    this.load(){ 
     var cb=onLoadComplete; 
     tags[uniqueID]=new Tag(userConfig,cb); 
     tags[uniqueID].load(); 
    }  
}).load(); 

我想在这里实现JavaScript锁。三个JavaScript标签对象被创建。 [新标签()]这些对象共享和修改PROJ中的一些公共数据。

我想通过执行标签释放锁定时访问公共数据。 setTimeout()中提到的这个负载正在调用PROJ的load()。

+0

您应该解决您的代码。有语法错误(这些{}}括号可能会被浏览器忽略,所以你不会看到它),并且没有'load'函数的定义。 – Groo 2011-12-29 18:44:18

+0

@Umesh Groo和FelixKing都声明,你的代码在合成上是不正确的,所以我们只能猜测你的问题。尽管这是从一个更大的背景中切割出来的,但请让它自我一致并且合理正确,否则你得到的答案只会是黑暗中的一个镜头。 – chuckj 2011-12-29 18:52:36

回答

1

我假设的代码实际上是这样的:

this.Tag = function(userConfig,callBack){  
     function loadConfig(){ 
       lock=false;    
       /* Do something privately having lock with me */ 
       lock=true; 
     }       
     this.load = function(){ 
       if(lock) loadConfig(); 
       else  setTimeout(load,1000); 
     } 
    return this; 
}; 

由于JavaScript是单线程的,这是不可能的load函数被调用,而loadConfig仍在运行。这意味着,这是不可能的lock变量是falseload,除非:

  1. 有一个return声明loadConfig其中lock设置为true之前返回执行
  2. 在函数中间引发异常,最后一行从不执行。

对于后一种情况,你可以使用try/finally块,以确保lock在异常的情况下重置:

 function loadConfig(){ 
      try { 
       lock=false;    
       /* Do something privately having lock with me */ 
      } 
      finally { 
       // this will get executed even if an exception is thrown 
       lock=true; 
      } 
     } 

底线是,lock是没有必要的,可以被完全删除。 load没有办法可以与loadConfig同时运行。

+0

谢谢Groo!它更好解释:) – 2011-12-29 18:58:45

3

您是否知道JavaScript只能在单个线程中运行?锁(并发性)没有太大的作用,除非你的内部函数实际上是递归的或者以某种方式调用load

请注意,我认为你的语法错了。

this.load(){ 
    if(lock) loadConfig(); 
    else  setTimeout(load,1000); 
} 

实际上是这样做的:

this.load(); // invoke load 

if(lock) loadConfig(); 
else  setTimeout(load,1000); 
+0

给出的代码非常简化并且最小化。即使JS运行在单线程中,也会创建同时运行的多个标签(标签对象)。 – 2011-12-29 18:18:25

+1

@Umesh:多次!==并发。 – 2011-12-29 18:19:36

+0

@ FelixKling,是的。我想说,这里创建了多个(并发)标记对象。你能帮忙吗? – 2011-12-29 18:23:36

0
window.setMinInterval=function(callback, delay){ 
    var lock=false; 
    return function(){ 
     if(lock){return;} 
     lock=true; 
     setTimeout(function(){lock=false;}, delay); 
     callback.apply(this, Array.prototype.slice.call(arguments, 0)); 
    }; 
}; 
var mousemoveHandler=function(event){ 
    document.title=event.clientX+","+event.clientY; 
}; 
window.onmousemove=setMinInterval(mousemoveHandler,500); 

这些代码演示事件触发频率限制