在浏览器中 JavaScript 是否可能并发 read/write read/write 冲突?
Is it possible for a concurrent read/write read/write collision in JavaScript in the browser?
我有这样一种情况,我正在进行几次(比如四次)ajax 调用(使用 AngularJS http get,如果这很重要)并且我希望每次调用都回调并增加一个计数器,这样我就可以知道所有(四个)线程何时完成。
我担心的是,由于 JavaScript 没有任何可与 Java 的 "synchronized" 或 "volatile" 关键字相媲美的东西,因此多个并发是可能的线程在递增计数器时发生碰撞,从而错过一些增量。
换句话说,两个线程同时来,都读取计数器,得到相同的值(例如100)。然后两个线程递增该计数器(到 101)并存储新值,看,我们错过了一个计数(101 而不是 102)!
我知道Java脚本应该是单线程的,但也有例外。
在浏览器中是否会出现这种情况,如果会出现,有什么防范措施吗?
就像你提到的,因为javascript是单线程的,我不认为这样的场景会发生,js变成多线程的唯一方法是当你使用webworkers时,但即使他们不共享相同的变量(他们克隆你传递的属性 js 对象,我在这里假设),所以应该有任何 read/write overlap
的情况
编辑
再想一想,假设有一个函数 onCounterIncreament
会在计数器递增时执行一系列操作,如果你在递增计数器后不立即调用它,而是使用 $watch
或其他东西timeout fn 检查计数器的变化,很有可能你错过了变化。
不,不可能(不会发生碰撞)。每个 AJAX 调用响应都可以被视为 JavaScript 消息队列中的一条消息。 JavaScript 运行时处理队列中的每条消息,直至完成,然后再处理下一条消息。换句话说,它调用事件的回调并运行完整的回调函数(以及它调用的所有函数,等等)直到完成,然后再移动到队列中的下一条消息。因此,不会并行处理两条消息(例如,AJAX 响应)。
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop
另外,我在JavaScript工作了很多年,可以保证它是这样工作的。
我有这样一种情况,我正在进行几次(比如四次)ajax 调用(使用 AngularJS http get,如果这很重要)并且我希望每次调用都回调并增加一个计数器,这样我就可以知道所有(四个)线程何时完成。
我担心的是,由于 JavaScript 没有任何可与 Java 的 "synchronized" 或 "volatile" 关键字相媲美的东西,因此多个并发是可能的线程在递增计数器时发生碰撞,从而错过一些增量。
换句话说,两个线程同时来,都读取计数器,得到相同的值(例如100)。然后两个线程递增该计数器(到 101)并存储新值,看,我们错过了一个计数(101 而不是 102)!
我知道Java脚本应该是单线程的,但也有例外。
在浏览器中是否会出现这种情况,如果会出现,有什么防范措施吗?
就像你提到的,因为javascript是单线程的,我不认为这样的场景会发生,js变成多线程的唯一方法是当你使用webworkers时,但即使他们不共享相同的变量(他们克隆你传递的属性 js 对象,我在这里假设),所以应该有任何 read/write overlap
的情况编辑
再想一想,假设有一个函数 onCounterIncreament
会在计数器递增时执行一系列操作,如果你在递增计数器后不立即调用它,而是使用 $watch
或其他东西timeout fn 检查计数器的变化,很有可能你错过了变化。
不,不可能(不会发生碰撞)。每个 AJAX 调用响应都可以被视为 JavaScript 消息队列中的一条消息。 JavaScript 运行时处理队列中的每条消息,直至完成,然后再处理下一条消息。换句话说,它调用事件的回调并运行完整的回调函数(以及它调用的所有函数,等等)直到完成,然后再移动到队列中的下一条消息。因此,不会并行处理两条消息(例如,AJAX 响应)。
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop
另外,我在JavaScript工作了很多年,可以保证它是这样工作的。