瀏覽器中的JavaScript是否可能發生並發讀/寫讀/寫沖突?

[英]Is it possible for a concurrent read/write read/write collision in JavaScript in the browser?


I have a situation where I am making several (say four) ajax calls (using AngularJS http get, if that matters) and I want each call to callback and increment a counter, so I can know when all (four) of the threads have completed.

我有一種情況,我正在制作幾個(比如說四個)ajax調用(使用AngularJS http get,如果這很重要)並且我希望每次調用回調並增加一個計數器,所以我可以知道所有(四個)線程何時有完成。

My concern is that since JavaScript does not have anything comparable to Java's "synchronized" or "volatile" keywords, that it would be possible for multiple concurrent threads to collide while incrementing a counter, thereby missing some increments.

我擔心的是,由於JavaScript沒有任何可與Java的“synchronized”或“volatile”關鍵字相媲美的東西,因此多個並發線程可能會在遞增計數器時發生沖突,從而錯過了一些增量。

In other words, two threads come at the same time, and both read the counter, getting the same value (for example 100). Then both threads increment that counter (to 101) and store the new value, and behold, we missed a count (101 instead of 102)!

換句話說,兩個線程同時出現,並且都讀取計數器,獲得相同的值(例如100)。然后兩個線程都遞增該計數器(到101)並存儲新值,不料,我們錯過了一個計數(101而不是102)!

I know that JavaScript is supposed to be single threaded, but there are exceptions.

我知道JavaScript應該是單線程的,但也有例外。

Is this situation possible in the browser, and if so, is there any way to guard against it?

這種情況在瀏覽器中是否可行,如果是這樣,有什么方法可以防范它嗎?

2 个解决方案

#1


4  

No, it is not possible (no collision will occur). Each AJAX call response can be considered a message on the JavaScript message queue. The JavaScript runtime processes each message on the queue to completion before processing the next. In other words, it calls the callback for the event and runs the full callback function (and all the functions it calls, and so on) to completion before moving onto the next message in the queue. Therefore, no two messages (e.g., AJAX responses) will be processed in parallel.

不,這是不可能的(不會發生碰撞)。每個AJAX調用響應都可以被視為JavaScript消息隊列中的消息。 JavaScript運行時在處理下一個消息之前處理隊列中的每個消息。換句話說,它調用事件的回調並運行完整的回調函數(以及它調用的所有函數,依此類推),然后再轉到隊列中的下一條消息。因此,不會並行處理兩個消息(例如,AJAX響應)。

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

Also, I've worked in JavaScript for many years and can guarantee this is how it works.

此外,我已經在JavaScript中工作了很多年,可以保證這是它的工作原理。

#2


3  

like you mentioned, since javascript is single threaded, I do not think such a scenraio would happen, the only way js becomes multi threaded is when you use webworkers, but even they do not share the same variables( they clone the attribute js objects you pass, i am assuming here), so there should be any case of read/write overlap

就像你提到的那樣,因為javascript是單線程的,我不認為這樣的場景會發生,js成為多線程的唯一方法就是你使用webworkers,但即使他們不共享相同的變量(他們克隆屬性js對象你傳遞,我假設在這里),所以應該有任何讀/寫重疊的情況

EDIT

on second thought, say there is function onCounterIncreament which would do a bunch of operation when counter increments, if you do not call it immediately after you increamenting counter, but use $watch or something timeout fn to check for change in counter, there is a good possiblity you might miss a change.

第二個想法,說有一個函數onCounterIncreament,它會在計數器遞增時執行一系列操作,如果你在遞增計數器后沒有立即調用它,但是使用$ watch或者某個超時fn來檢查計數器的變化,有一個很可能你可能會錯過一個改變。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/01/11/7250701f1e10f296bc807b577fd9b292.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com