2015-04-23 99 views
0

的考慮下面的JavaScript代碼(或等價的東西):的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編寫的,這可能不起作用...

回答

1

JavaScript不是多線程的,所以你的回調實際上已經是「原子」了。 buf只能在對回調的調用之間進行更改。

+0

非常感謝。我認爲表達被確保是原子的,但不是完全關閉。只是爲了演示:'var hello = {val:「hello」}; setTimeout(function(){hello.val =「bye」;}); console.log(「Hello is now」,hello); while(hello.val ==「hello」); console.log(「Hello is now」,hello);'將凍結repl。 – fakedrake