JavaScript:异步事件回调的线程安全? (我需要 'volatile' 还是什么?)
JavaScript: thread safety with asynchronous event callbacks? (do I need 'volatile' or something?)
假设我有以下代码来预加载 2 个图像,并且仅在 两个 个图像都已加载后才执行某些操作:
var numLoaded = 0;
function OnImageLoaded()
{
numLoaded++;
if (numLoaded==2) alert("Got 'em!");
}
var a = new Image();
var b = new Image();
a.onload = OnImageLoaded;
b.onload = OnImageLoaded;
a.src = 'foo.jpg';
b.src = 'bar.jpg';
分配 a.src
和 b.src
会导致两个图像都在后台加载,然后调用 OnImageLoaded()
然后它们就准备好了。
显然 if (numLoaded==2)
之后的代码应该只 运行 一次。
现在,是否有可能发生这种情况:
- 加载第一张图片,调用函数,
numLoaded++
将计数器增加到 one,
- 加载第二张图片,调用函数(在不同的线程中),
numLoaded++
将计数器增加到 two,
- 第一个线程检查
numLoaded==2
现在为真,因此代码被执行,
- 第二个线程也检查
numLoaded==2
这仍然是正确的,所以应该 运行-once 代码被执行 again ← 问题!
这是一个机会吗(尽管很小),我该如何避免呢?在其他语言中,我会为此使用关键部分或互斥锁,或者使 numLoaded 易变并执行 n=(++numLoaded)
或其他操作,但我如何在 JS 中执行此操作?
Javascriptdoes not run concurrently正常情况下。使用 Node.js 有很多方法可以做到这一点,但这相当困难,在典型情况下您不必担心。
假设我有以下代码来预加载 2 个图像,并且仅在 两个 个图像都已加载后才执行某些操作:
var numLoaded = 0;
function OnImageLoaded()
{
numLoaded++;
if (numLoaded==2) alert("Got 'em!");
}
var a = new Image();
var b = new Image();
a.onload = OnImageLoaded;
b.onload = OnImageLoaded;
a.src = 'foo.jpg';
b.src = 'bar.jpg';
分配 a.src
和 b.src
会导致两个图像都在后台加载,然后调用 OnImageLoaded()
然后它们就准备好了。
显然 if (numLoaded==2)
之后的代码应该只 运行 一次。
现在,是否有可能发生这种情况:
- 加载第一张图片,调用函数,
numLoaded++
将计数器增加到 one, - 加载第二张图片,调用函数(在不同的线程中),
numLoaded++
将计数器增加到 two, - 第一个线程检查
numLoaded==2
现在为真,因此代码被执行, - 第二个线程也检查
numLoaded==2
这仍然是正确的,所以应该 运行-once 代码被执行 again ← 问题!
这是一个机会吗(尽管很小),我该如何避免呢?在其他语言中,我会为此使用关键部分或互斥锁,或者使 numLoaded 易变并执行 n=(++numLoaded)
或其他操作,但我如何在 JS 中执行此操作?
Javascriptdoes not run concurrently正常情况下。使用 Node.js 有很多方法可以做到这一点,但这相当困难,在典型情况下您不必担心。