2012-03-21 18 views
4

私は単純なコードを持っているとしましょう。JS&並行性の問題?

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回呼び出されると思います。どの質問がまだ開いていますか? – zod

+0

私は多くの考えを持っていますが、それらのすべてが真実ではありません。 – hades

答えて

3

はJavaScriptは、このようにあなたが気にする必要はありません、( sの例外を除いて)、シングルスレッドです並行性について。本質的には、すべてのコードブロックは、どれくらい長い間、アトミックです。 incrementAndModify()がCPUを大量に消費し、AJAX応答が到着した場合、現在のincrementAndModify()が終了して唯一のスレッドを解放するまでコールバックは実行されません。

これは、同期AJAX呼び出しが推奨されない理由です.AJAX要求には、他のコードを実行できない(実行スレッドが不必要に占有される)時間がかかることがあります。これにより、他のユーザーイベントは処理されないため、GUIは「フリーズ」します。

も参照してください

ところで、この:

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

は次のように書くことができます。

doAjaxGetWithCallback(incrementAndModify); 
+0

私はむしろそれを半分のスレッド言語と呼んでいます))) – shabunc

+0

「すべてのコードブロックがアトミック」であっても、「あなたは並行性について心配する必要はありません」というあなたの主張は真実ではないと思います。私は知らなかった。並行処理の問題は、何らかの形で状態を共有するコールバック(またはプロミスまたはオブザーバブル)があるときには、引き続き発生する可能性があります。次のコールバックが開始される前にコールバックが完全に終了したとしても、これらのコールバックが発生する順序を知らないために余裕を持たなければなりません。 1つのコールバックで簡単ですが、複雑さは複数のコールバックで膨大になります。 –

+0

@shabuncなぜですか?ウェブワーカーのため? – Taurus

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/

+0

と、たくさんのタイマーと1つの共有リソースがあった場合、どのようにこのクレイジーコードで同期しますか? – hades

+0

彼らはまだすべてが同じ '私は'にアクセスしている、それは彼らがあなたが心配する必要があると呼ばれるかもしれない順序です。 JSは非常にシンプルですが、このようなことを処理するためにスレッド言語で行うような派手な作業は必要ありません。このコードを同期させる方法は、タイマーから取り出すことです。私はあなたが実際に解決しようとしている問題について少しは分かりませんので、もっと詳細な情報が役立つでしょう。 –

+0

私は問題を解決しようとしていません、問題を防ぐために試しています;) – hades