Javascript 原子系列操作

Javascript atomic series of operations

给定以下 javascript 代码(或等效代码):

var buf = [];
setInterval(function () {
  buf.push("token");
  // If buf has something pushed here we are screwed
  if (buf.length == 1) {
    sendCriticalLog();
  }
});

setInterval(function () {
  buf.push("other token");
});

有没有办法保证第一个区间的函数对于buf是原子的?

我唯一能想到的方法是:

function atomic(lock, cb){
  var finish = function () {
    lock.callbacks = lock.callbacks.slice(1);
    if (lock.callbacks.length) {
      lock.callbacks[0].call();
    }
  };

  cb = cb.bind(null, finish);
  if ((lock.callbacks = (lock.callbacks || []).concat([cb])).length == 1) {
    // Nothing is running
    lock.callbacks[0]();
  };
}

var buf = [];
setInterval(function () {
  atomic(buf, function () {
    buf.push("token");
    // If buf has something pushed here we are screwed
    if (buf.length == 1) {
      sendCriticalLog();
    }
  });
});

setInterval(function () {
  atomic(buf, function () {
    buf.push("other token");
  });
});

但这是在 ((lock.callbacks = (lock.callbacks || []).concat([cb])).length == 1) 将保证以原子方式处理的假设下。例如,如果 concat 写成普通的 javascript 这可能不起作用...

JavaScript 不是多线程的,所以你的回调实际上已经 "atomic"。 buf 只能在回调调用之间更改。