浏览器中的JavaScript是否可能发生并发读/写读/写冲突?

时间:2015-01-11 05:14:17

标签: javascript angularjs multithreading concurrency concurrent-programming

我有一种情况,我正在制作几个(比如四个)ajax调用(使用AngularJS http get,如果这很重要)我希望每次调用回调并增加一个计数器,这样我就可以知道什么时候全部(四个)线程已经完成。

我担心的是,由于JavaScript没有任何可与Java"同步"或者" volatile"关键字,多个并发线程可能会在递增计数器时发生冲突,从而错过一些增量。

换句话说,两个线程同时出现,并且都读取计数器,获得相同的值(例如100)。然后两个线程都递增该计数器(到101)并存储新值,不料,我们错过了一个计数(101而不是102)!

我知道JavaScript应该是单线程的,但也有例外。

浏览器中是否存在这种情况?如果是这样,有什么方法可以防范它吗?

2 个答案:

答案 0 :(得分:4)

不,不可能(不会发生碰撞)。每个AJAX调用响应都可以被视为JavaScript消息队列中的消息。 JavaScript运行时在处理下一个消息之前处理队列中的每个消息。换句话说,它调用事件的回调并运行完整的回调函数(以及它调用的所有函数,依此类推),然后再转到队列中的下一条消息。因此,不会并行处理两个消息(例如,AJAX响应)。

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop

此外,我在JavaScript工作多年,可以保证这是它的工作原理。

答案 1 :(得分:3)

像你提到的那样,因为javascript是单线程的,我不认为这样的场景会发生,js成为多线程的唯一方法就是你使用webworkers,但即使他们不共享相同的变量(他们克隆属性)你传递的js对象,我假设在这里),所以应该有任何读/写重叠的情况

<强> 修改

第二个想法,比如说有一个函数onCounterIncreament会在计数器递增时执行一系列操作,如果你在递增计数器后没有立即调用它,但是使用$watch或者某些超时fn为了检查柜台的变化,你可能会错过一个改变。