2011-04-10 64 views
0

我在谷歌瀏覽器中同時調用多個事件處理程序時遇到此問題。 下面的代碼在書籤創建事件的情況下觸發eventHandler函數。chrome javascript事件處理問題

chrome.bookmarks.onCreated.addListener(eventHandler); 

當通過拖動幾個bookmarkbar鏈路從Firefox到鉻創建了多個書籤,例如,多個事件處理程序功能被同時運行,這導致不希望的效果。我需要確保一次只運行一個eventHandler實例,並且事件按先到先得的原則處理。有沒有在JavaScript的方式來確保這一點?

回答

0

我不認爲有一個很好的方法來做到這一點。 JavaScript的重點在於它是基於事件的。

一種破解它的方法可能是使用setTimeout,其超時時間很短。

var timeout; 

chrome.bookmarks.onCreated.addListener(function(ev) { 
    clearTimeout(timeout); 
    timeout = setTimeout(function() {eventHandler(ev);}, 5); 
}); 
+0

我不認爲這是工作 – anp 2011-04-10 11:59:20

+0

@anp爲什麼呢? – 2011-04-10 12:30:09

+0

即使有延遲,輸出也是一樣的 – anp 2011-04-11 02:49:51

2

正如Jakub指出的那樣,異步事件處理是JavaScript的優點之一。我建議重新考慮你的應用程序流程來支持這一點,而不是試圖序列化它。此外,你並沒有承諾事件觸發的順序是你期望他們觸發的順序。拖動多個書籤可以按任意順序生成事件。

如果您確實需要確保您的程序按照它們進來的順序處理事物,並且一次只處理一個項目,則可以將您的邏輯分爲兩部分:eventHandler本身可以是填充您需要以某種方式處理事件隊列,並且可以在超時驅動循環中運行另一個函數,檢查隊列,關閉項目並對其進行處理。類似於以下(未經測試)代碼:

function SerializedEventHandler() { 
    chrome.bookmarks.onCreated.addListener(this.enqueue.bind(this)); 
} 

SerializedEventHandler.prototype = { 
    queue_: [], 

    timer_: null, 

    enqueue: function (e) { 
    this.queue_.push(e); 
    this.startProcessing(); 
    }, 

    startProcessing: function() { 
    if (!this.timer_) 
     this.timer_ = setTimeout(this.process.bind(this), 100); 
    }, 

    process: function() { 
    if (this.queue_.length) { 
     var item = this.queue_.shift(); 
     // do something with `item` 
     this.timer_ = clearTimeout(this.timer_); 
     this.startProcessing(); 
    } 
    } 
}; 

這有道理嗎?

+0

順序對於避免競爭條件很重要。雖然我還沒有測試過你的代碼,但我想我會採用這種方法。在設定時間的時候,有些事件可能會經過嗎? – anp 2011-04-14 03:58:52