Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS&;并发问题?_Javascript_Ajax_Javascript Events_Concurrency_Web Worker - Fatal编程技术网

Javascript JS&;并发问题?

Javascript JS&;并发问题?,javascript,ajax,javascript-events,concurrency,web-worker,Javascript,Ajax,Javascript Events,Concurrency,Web Worker,假设我有简单的代码 var counter = 0; var sharedResource = [];//some shared resource function incrementAndModify(){ if(counter == 0) { sharedResource.push(Math.random());//very sensitive data counter++; } } function init(){ incrementAndM

假设我有简单的代码

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

浏览器中的JavaScript是单线程的(s除外),因此您不必担心并发性。本质上,每个代码块都是原子的,不管有多长。如果
incrementAndModify()
执行一些非常耗时的CPU密集型操作,并且AJAX响应到达,则在当前
incrementAndModify()
完成并释放唯一线程之前,不会执行回调

这也是不鼓励同步AJAX调用的原因:AJAX请求可能需要一些时间,在此期间无法执行其他代码(执行线程被不必要地占用)。这会导致GUI“冻结”,因为不会处理其他用户事件

另见
顺便说一句:

doAjaxGetWithCallback(function(){incrementAndModify();});
可以这样写:

doAjaxGetWithCallback(incrementAndModify);

不要担心这只会提醒你一次

// sync example
var happened = false;

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

function dontDoTwice() {
  if (!happened) {
    alert("ALERT! ALERT! ALERT!");
    happened = true;
  }
}
稍微复杂一点的例子:

是的,
incrementAndModify()函数将始终以原子方式运行。这是因为javascript的特性


有关更多详细信息,请参阅。

原子意味着什么?我想会一个接一个叫三遍。哪一个问题仍然悬而未决?我有很多想法,但并非所有想法都是正确的。如果你有多个计时器和一个共享资源,你会如何在这段疯狂的代码中进行同步?它们仍然访问相同的
I
,这正是你需要担心的调用顺序。JS非常简单,您不能也通常不需要像在线程语言中那样处理这些东西。使此代码同步的方法是将其从计时器中取出。不过,对于您实际试图解决的问题,我有点不确定,因此也许更多的细节可以帮助我提供更有用的答案。我不是在试图解决问题,而是在试图预防问题;)噢,您担心
if(count==0)
可能会被调用两次。答案是否定的。回调将在稍后发生。我会用更好的例子更新我的!我不认为您的断言“因此您不必担心并发性”是正确的,即使“每个代码块都是原子的”,我不知道这一点。当您有以某种方式共享状态的回调(或承诺或可观察对象)时,并发问题肯定仍然会发生。即使回调在下一个回调开始之前完全完成,您也必须考虑到不知道这些回调发生的顺序。一次回调很简单,但显然,多次回调的复杂性会变得很大。