删除事件循环中排队的javascript消息

删除事件循环中排队的javascript消息,javascript,javascript-events,event-loop,Javascript,Javascript Events,Event Loop,在javascript中,如果触发了一个事件,并且相应的回调被添加到javascript引擎事件循环的消息队列中。是否可以通过javascript代码将其从队列中删除 请注意,事件的调用频率很高,因此可以在执行任何javascript代码之前将其添加到事件队列中。我没有看到描述说removeEventListener实际上遍历消息队列并删除相应的事件;要再次检查removeEventListener是否确实执行了此操作,并且此功能在所有javascript引擎中的实现方式相同。标准javascr

在javascript中,如果触发了一个事件,并且相应的回调被添加到javascript引擎事件循环的消息队列中。是否可以通过javascript代码将其从队列中删除


请注意,事件的调用频率很高,因此可以在执行任何javascript代码之前将其添加到事件队列中。我没有看到描述说removeEventListener实际上遍历消息队列并删除相应的事件;要再次检查removeEventListener是否确实执行了此操作,并且此功能在所有javascript引擎中的实现方式相同。

标准javascript不提供对事件队列的任何直接访问。您可以侦听事件(通常使用
.addEventListener()
或注册回调,当轮到它们时,该事件将触发并调用回调。或者,可以使用
.removeEventListener()
或取消特定操作(如
clearTimeout()
)删除某些侦听器,但无法直接访问管理事件队列

为了做到这一点,您可能必须在虚拟机中包含本机代码,而如何做到这一点将是非标准的,并且特定于特定的Javascript虚拟机

如果您真的希望能够轻松地防止回调多次被调用,那么您可以创建一个小存根来实现这一点

function callOnce(fn) {
   var called = false;
   return function() {
      if (!called) {
          called = true;
          return fn.apply(this, arguments);
      }
   }
}


// create a callOnce function stub for myFunction
var cb = callOnce(myFunction);

obj1.addEventListener("click", cb);
obj2.addEventListener("click", cb);
obj3.addEventListener("click", cb);

myFunction
仅在第一个事件调用时被调用一次。之后,它将被定义
cb
时创建的callOnce存根阻止。

是。可以从对象解除事件绑定

  • 如果已使用
    addEventListener
    附加事件,则使用
    removeEventListener
    将其删除

  • 如果您使用了jQuery
    .bind()
    ,则使用
    .unbind()
    将其删除

  • 如果您使用了jQuery
    .on()
    ,则使用
    .off()
    将其删除

  • 如果使用
    attachEvent
    ,则可以使用
    detachEvent()

  • 如果使用
    onclick
    或其他类似函数,则只需将其设置为null即可将其删除。

    例如,obj.onclick=null


是否可以将其从队列中删除?当然可以,您可以给出一个这样做的用例吗?如果我想防止回调被调用两次,我可以在回调中添加一个标志来检查它是否已经被调用,但我想知道是否有其他方法可以正确执行。请注意,事件的调用频率很高,因此可能会添加到o在我运行任何javascript代码之前,请先检查事件队列。我只是没有看到说明removeEventListener实际上遍历了消息队列并删除了相应的事件;我想再次检查它在所有javascript引擎中的实现方式是否相同。@hindmost您能为您的声明提供文档吗
removeEventListener
删除已经排队的事件?如果我删除了VentListener,放入队列中的相应消息会被删除吗?或者它只会阻止将来的事件触发?@Gooly-从外部无法判断,因为这取决于单个JVM实现,坦白说,这无关紧要,因为它不会造成任何不同nce也是。如果你告诉我们你真正想解决的问题,而不是问这些理论问题,我们可能会帮助得更好。@Gooly-在其他地方的另一条评论中,你提到了防止回调被调用两次。你可以很容易地创建一个回调存根,防止任何回调被调用两次,然后每当您想要注册一个单次使用回调时,您只需执行类似于
obj.addEventListener(“eventname”,callOnce(myFunc))的操作即可
并且callOnce包装器会为您处理它。因此,如果removeEventListener已经在队列中,它可能不会起作用,对吗?如果callOnce函数不适合我的情况,那么在回调中添加标志是一种标准的方法吗?
callOnce()
比添加标志更简单,因为它是一种可重用的标志机制。请参阅我在回答中提供的示例实现。将来,如果您在问题中描述您试图解决的实际问题,而不是询问您正在寻求的解决方案的理论问题,您将获得更快、更丰富的答案。我添加了一些更多描述,我正在考虑事件已经触发的情况。我想知道您给出的示例是否仍然有效。问题不在于如何从对象解除事件绑定(jQuery给出了多么不幸的表达式),而是如何管理已经触发并等待执行的事件。