JavaScript:线程安全与异步事件回调?(我需要'挥发物'还是什么?)

JavaScript: thread safety with asynchronous event callbacks? (do I need 'volatile' or something?)

本文关键字:挥发物 是什么 安全 线程 异步 JavaScript 回调 事件      更新时间:2023-09-26

假设我有以下代码来预加载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.srcb.src导致两个图像都在后台加载,并且OnImageLoaded()被调用,然后它们准备好了。

显然if (numLoaded==2)之后的代码应该只运行一次。

现在,有这种可能性吗?

  1. 第一个图像被加载,函数被调用,numLoaded++将计数器增加到一个
  2. 第二个图像被加载,函数被调用(在不同的线程中),numLoaded++将计数器增加到两个
  3. 第一个线程检查numLoaded==2,现在是true,所以代码被执行,
  4. 第二个线程也检查numLoaded==2,这仍然是真的,所以应该运行一次的代码被执行再次←问题!

这是一个机会(尽管非常小),我如何避免这种情况?在其他语言中,我会为此使用临界区,或互斥锁,或使numLoaded易失性并执行n=(++numLoaded)或其他东西,但我如何在JS中进行此操作?

Javascript在正常情况下不能并发运行。有一些方法可以使用Node.js来实现,但这相当困难,在典型情况下你不必担心。