2011-12-29 93 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); 

這些代碼演示事件觸發頻率限制