我们假设我有简单的代码;
var counter = 0;
var sharedResource = [];//some shared resource
function incrementAndModify(){
if(counter == 0) {
sharedResource.push(Math.random());//very sensitive data
counter++;
}
}
function init(){
incrementAndModify();
doAjaxGetWithCallback(function(){incrementAndModify();});
incrementAndModify();
}
所以问题是:incrementAndModify()函数是否会以原子方式运行?我读过,JS在单线程上运行,并且不存在任何并发问题。但问题仍然存在(至少对我而言)。
而不是
doAjaxGetWithCallback(function(){incrementAndModify();});
我可以这样写:
doAjaxGetWithCallback(function(){
doSomeCrazyStuffThatDoesNotUseSharedResource();
incrementAndModify();
doSomeOtherCrazyStuffThatDoesNotUseSharedResource();
});
答案 0 :(得分:3)
浏览器中的JavaScript是单线程的(web-worker s除外),因此您不必担心并发问题。本质上 - 每个代码块都是原子的,无论多长时间。如果incrementAndModify()
执行一些非常耗费CPU的耗时操作并且AJAX响应到达,则在当前incrementAndModify()
完成并释放唯一线程之前,不会执行回调。
这也是不鼓励同步AJAX调用的原因:AJAX请求可能需要一些时间,在此期间不能执行其他代码(执行线程被不必要地占用)。这会导致GUI“冻结”,因为没有其他用户事件被处理。
BTW:
doAjaxGetWithCallback(function(){incrementAndModify();});
可以这样写:
doAjaxGetWithCallback(incrementAndModify);
答案 1 :(得分:0)
不要害怕这只会警惕一次。
// sync example
var happened = false;
setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);
function dontDoTwice() {
if (!happened) {
alert("ALERT! ALERT! ALERT!");
happened = true;
}
}
稍微复杂的例子: http://jsfiddle.net/7BZ6H/1/
答案 2 :(得分:0)
是的,incrementAndModify()
函数将始终以原子方式运行。这是因为javascript的Run-to-Completion功能。