質問

私は常にダウンカウントタイマーがあるWebアプリケーションを持っています。一方、クライアントが頻繁に多くの時間をタイマーに追加されているかどうかを確認するためにサーバとチェックします。コードは次のようになります。

function tick() {
    // This function is called once every second
    time -= 1;
    redisplay(time);
};
function update(newtime) {
    // This function is called whenever the ajax request
    // to the server yields a new time
    time = newtime;
};

これは、当然のことながら、少し複雑よりもですが、固有の競合状態を見ることができます。どのようなアップデートやダニの機能の両方が同時にtimeを変更しようとしているか?

これを行う簡単な方法があるか、そうでなければ、誰かが私はより多くを学ぶことができるリソースに向けて私を指すことができます:

率直に言って、私は、同時実行の問題のこの種に対処する方法を理解するためにほぼ十分なJavaScriptを知らないのか?

ありがとうございます。

役に立ちましたか?

解決

Javascriptが同時に実行されないため、

あなたは、競合状態を持っていません。

別の非同期操作から別のコールバックを呼び出すことができます前に、

コールバックが非同期操作(AJAX、setTimeout、など)から発射されるたびに、そのコールバックが実行を終了しなければなりません。 update()が実行されているのであれば、他のJavascriptではありません。 update()が終了したら、非同期動作から他のコールバックは(例えば、tick())焼成することができます。興味深いことに、これはまた、なぜsetTimeoutであり、その同類がタイムアウトに達する正確な瞬間に実行することが保証されていません:他のいくつかのjavascriptのコールバックの実行をブロックすることができます。

http://ejohn.org/blog/how-javascript-timersをチェック-work / のすべてこれがどのように機能するかについていくつかの良い情報を参照してください。

他のヒント

Javascriptがシングルスレッドです。何の競合状態がありません。実行時にオーバーラップするtime = newtime;time -= 1; 2ライン分のJavaScriptで方法はありません。実際には、二つの機能が重複しないことが保証されています。そのうちの一つが実行され、その後、他が実行されます。

私が間違っていた:これで問題が解決しません! (コードの後、について説明)

NEWTIME = false;
function tick() {
    // This function is called once every second
    if (NEWTIME) {
        time = NEWTIME;
        NEWTIME = false;
    }
    time -= 1;
    redisplay(time);
};
function update(newtime) {
    // This function is called whenever the ajax request
    // to the server yields a new time
    NEWTIME = newtime;
};

この間違った解決策の問題であることをあなただけの変数timeに変数NEWTIMEからレースコンディションの問題を移動するこの方法をやってます。

ただ、このことを考える:tickの実行は継続する前に、と呼ばれ、time = NEWTIME;が値NEWTIMEを取得します更新し、今ラインXに到達し、実行します。今ダニ実行はNEWTIME = false;の実行を継続します。あなたがXNEWTIME値と更新のような効果を失ってしまった。この方法で()を呼び出す!

問題は、いくつかのセマフォを必要とします。私は前回の1が終了した後に、AJAXを送信するためにその多くを行います。あなたの場合は少し似ている;)

そのような何かを試してみてください。これは、AJAXコールバックと衝突時間を減少するための試みをすべて無視してください。

window.TimeKeeper = new function(){
this.time=0; //initial value, whatever
this.isopen=true;

this.decrement = function(){ 
 if(this.isopen){
  this.time--;
  redisplay(this.time);
  }
 }
this.set = function(val){
 if(this.isopen){
  this.isopen=false;
  this.time=val;
  this.isopen=true;
  } else {
  //another AJAX callback is modifying time. 
   //You can enqueue current value and put it later
  }
 }

}

function tick() {
    TimeKeeper.decrement();

};
function update(newtime) {
    TimeKeeper.set(newtime);
};

もう一つ - のsetTimeoutは、新しいスレッドのように動作し、私はブラウザが同期MEMのアクセスを行うことを期待するので、価値がデクリメントする前に成長しなかったかどうかを確認するために十分であるかもしれません。しかし、上記のソリューションは、より柔軟かつ安全である。

そして、もう一つの小さなヒント - あまりにも頻繁にAJAXを照会避ける - それは余分な問題が発生することがあり - 異なるために戻ってくるリクエストのように送られ、およびFirefoxのメモリ使用量があまりにも多くのAJAXの多くの分を構築するよりもを;)

限り、あなたはあなたの現在の時間にいくつかのより多くの秒を追加すると、あなたは問題ないはずです。

その代わりtime = newtime;を行うのあなたが心配している秒を失うことはありません。この方法をtime += newtime;てみます。

それでも、あなただけ失っている第二最悪でます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top