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 只能在回调调用之间更改。
给定以下 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 只能在回调调用之间更改。