如何在加载异步的HTML元素之间创建信号量

Him*_*ack 6 html javascript semaphore

我有一个HTML页面,一个多次出现的元素,并运行相同的JS.问题是,我希望它只有在第一个运行它时才能执行特定的功能(他的兄弟姐妹从未运行它 - YET).

我需要信号量才能在它们之间进行同步.我无法知道如何在JS中声明变量和以这种方式执行信号量.

T.J*_*der 7

有很多方法.

你需要在某处放置一面旗帜.在没有任何其他东西的情况下,你可以把它戴上window,但使用一个不太可能与其他任何东西冲突的名字.

那么JavaScript非常简单:

if (!window.myUniqueNameFlag) {
    window.myUniqueNameFlag = true;
    // Do your processing
}
Run Code Online (Sandbox Code Playgroud)

但是,window如果你可以避免它,那么把东西放在上面并不理想,尽管这是常见的做法.(您在全局范围声明的任何函数或变量都是var.)的属性.)

如果您的函数已在全局范围内声明(因此已占用符号),则可以执行此操作以避免创建第二个符号.代替:

function foo() {
    // ...your processing...
}
Run Code Online (Sandbox Code Playgroud)

做这个:

var foo = (function() {
    var flag = false;

    function foo() {
        if (!flag) {
            flag = true;
            // ...your processing...
        }
    }

    return foo;
})();
Run Code Online (Sandbox Code Playgroud)

这看起来很复杂,但事实并非如此:我们定义了一个匿名函数,我们在其中定义一个变量和一个嵌套函数,然后我们返回嵌套函数引用并将其分配给外部window变量.你可以打电话给foo你,你会得到嵌套的功能.嵌套函数具有对变量的持久引用,foo因为它是对变量的闭包,但没有其他人可以看到它.它是完全私密的.

一个第三选择是仅使用标志的功能对象本身:

function foo() {
    if (!foo.flag) {
        foo.flag = true;
        // ...do your processing...
    }
 }
Run Code Online (Sandbox Code Playgroud)

函数只是能够被调用的对象,因此您可以向它们添加属性.

  • @oshafran:浏览器上的JavaScript保证是单线程的,禁止使用新的[web workers](http://www.w3.org/TR/workers/)内容,这需要明确的语法.所以上面的**在浏览器上是**原子的.如果您正在使用其他一些环境,并且*如果*该环境是多线程的,则您将使用环境提供的同步机制.但是你说这个基于浏览器,所以不需要. (5认同)
  • 这不是原子操作.从理论上讲,两个元素都可以在传递if条件之前分配变量 (2认同)