使用JavaScript事件处理的竞争条件?

使用JavaScript事件处理的竞争条件?,javascript,jquery,html,javascript-events,Javascript,Jquery,Html,Javascript Events,我们知道JavaScript是单线程的,但我们想确认我们对JavaScript中异步事件处理的理解。更重要的是,我们想确认我们没有暴露在潜在的比赛条件下 从概念上讲,我们的移动应用程序的工作原理如下: 当加载移动页面时,我们调用函数foo 在foo的末尾,如果计数器大于0,我们使用setTimeout再次调用foo(延迟1秒)。如果计数器点击0,我们将加载一个新页面。超时保存在变量中 如果点击一个按钮,我们调用函数do\u tap,并清除步骤2中保存的超时变量(以及执行其他操作) dou_-ta

我们知道JavaScript是单线程的,但我们想确认我们对JavaScript中异步事件处理的理解。更重要的是,我们想确认我们没有暴露在潜在的比赛条件下

从概念上讲,我们的移动应用程序的工作原理如下:

  • 当加载移动页面时,我们调用函数
    foo

  • foo
    的末尾,如果计数器大于
    0
    ,我们使用
    setTimeout
    再次调用
    foo
    (延迟1秒)。如果计数器点击
    0
    ,我们将加载一个新页面。超时保存在变量中

  • 如果点击一个按钮,我们调用函数
    do\u tap
    ,并清除步骤2中保存的超时变量(以及执行其他操作)

  • dou_-tap
    foo
    都更新相同的页面元素,我们想确认它们不会互相踩踏

    问题:

  • 假设在执行
    foo
    的过程中发生点击。浏览器队列
    是否会在
    foo
    完成后点击
    开始执行?换句话说,我们是否保证一旦
    foo
    启动,就永远看不到执行
    foo
    dou_-tap
    的交错

  • 如果先点击怎么办
    do_tap
    保证在
    foo
    开始之前完成,对吗


  • 事件执行以单线程方式进行,直到事件得到处理。在此之前,不会启动其他事件循环

    换句话说,当处理程序为某个事件运行时,任何其他事件的处理程序都不会中断它


    因此,问题1和问题2的答案都是“是”。(当然,这是排除浏览器错误,但如果你考虑到这一点,你就走不了多远。这并不是说有任何同步原语可以依靠。我这么说只是因为Safari有一段时间可以发射“DOMready”事件在运行另一个“DoMeDead”事件处理程序的过程中。然而,这显然是一个错误。

    < P>只要第一个dodoTApp()的事情是清除超时,就不会有机会在DOOTApp()的执行过程中运行FO。但是,如果在foo()中启动了一个异步进程(例如数据库请求),那么当foo()完成其请求时,访问Do_tap()中的数据库可能会有一个潜在的等待,并且如果foo()有一个回调函数,理论上可以在Do_tap()之后调用该函数已完成执行。

    除了web工作者和协作框架或窗口(此处不使用),Javascript在给定窗口中是单线程的,因此该窗口中不会同时运行两个执行线程。因此,在使用线程时,您永远不必担心可能是一个典型问题的竞争条件

    在封面下,Javascript有一个事件队列。您当前的执行线程将运行到完成,然后当它完成时,javascript解释器将检查事件队列以查看是否还有更多的事情要做。如果是这样,它将触发该事件并启动另一个执行线程。几乎所有的事情都会经过这个事件队列(计时器、按键事件、调整大小事件、鼠标事件等等)


    您可以阅读更多关于它的内容,并在其中一篇文章中看到关于这个主题的大量相关参考资料。

    我没有听到其他人这样说,但我认为#2的答案是,不同的浏览器实现可以而且确实会以微妙的方式不同,首先处理哪些排队事件。不,不存在交叉的可能性,但语言规范并不保证是先处理setTimeout(func,0)还是鼠标事件,实际上可能很重要。而setTimeout(func,100)的处理时间保证晚于当前处理事件期间收到的挂起事件


    只是说说而已

    谢谢,我们只是想确认一下!dou_tap()和foo()都更新同一个页面元素,我们希望确保它们不会相互攻击。再次感谢您的肯定。由于执行是单线程的,
    foo
    不可能在返回
    Do\u tap
    之前开始执行(反之亦然)。阅读本文,您将了解浏览器中的执行队列是如何工作的:这几乎是真的,除了帧有单独的执行上下文,如果它们都访问相同的数据,如
    top.myVariable
    ,则可能存在竞争条件。查看并搜索该页面中的race我还想提及Chrome扩展,在该扩展中可以有多个单独的执行上下文。我还没有发现比赛条件经常发生,这在很大程度上取决于你在建造什么,但它确实发生了。