2011-04-10 63 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