简体   繁体   English

Javascript 和并发问题?

[英]Javascript and concurrency issues?

Let's assume I have simple code:假设我有简单的代码:

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();
}

So the question is: Will incrementAndModify() function be run atomically or not?所以问题是: incrementAndModify()函数是否会以原子方式运行? I've read, that JS run on single thread and there can't be any concurrency issues.我读过,JS 在单线程上运行,并且不会有任何并发​​问题。 But the question is still open (at least for me).但问题仍然存在(至少对我而言)。

Instead of:代替:

doAjaxGetWithCallback(function(){incrementAndModify();});

I could write something like:我可以这样写:

doAjaxGetWithCallback(function(){
doSomeCrazyStuffThatDoesNotUseSharedResource();
incrementAndModify();
doSomeOtherCrazyStuffThatDoesNotUseSharedResource();
});

JavaScript in the browser is single-thread (with exception to s), thus you don't have to bother about concurrency.浏览器中的 JavaScript 是单线程的( 除外),因此您不必担心并发性。 Essentially - every code block is atomic, no matter how long.本质上 - 每个代码块都是原子的,无论多长。 If incrementAndModify() does some very CPU-intensive time-consuming operations and AJAX response arrives, the callback will not be executed until the current incrementAndModify() finishes and releases the only thread.如果incrementAndModify()做了一些非常消耗 CPU 的耗时操作并且 AJAX 响应到达,则回调将不会执行,直到当前incrementAndModify()完成并释放唯一线程。

This is also the reason why synchronous AJAX calls are discouraged: AJAX request can take some time during which no other code can be executed (execution thread is unnecessarily occupied).这也是不鼓励同步 AJAX 调用的原因:AJAX 请求可能需要一些时间,在此期间无法执行其他代码(执行线程被不必要地占用)。 This causes the GUI to "freeze", because no other user events are handled.这会导致 GUI“冻结”,因为没有处理其他用户事件。

See also也可以看看

BTW this:顺便说一句:

doAjaxGetWithCallback(function(){incrementAndModify();});

can be written like this:可以这样写:

doAjaxGetWithCallback(incrementAndModify);

Yep, the incrementAndModify() function will always run atomically.是的, incrementAndModify()函数将始终以原子方式运行。 That's because of the Run-to-Completion feature of javascript.这是因为 javascript 的Run-to-Completion特性。

See Why no concurrency control tool in javascript for more details.有关更多详细信息,请参阅为什么在 javascript 中没有并发控制工具

Have no fear this will only ever alert once.不用担心这只会提醒一次。

// sync example
var happened = false;

setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);

function dontDoTwice() {
  if (!happened) {
    alert("ALERT! ALERT! ALERT!");
    happened = true;
  }
}

Slightly more complex example: http://jsfiddle.net/7BZ6H/1/稍微复杂一点的例子: http : //jsfiddle.net/7BZ6H/1/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM