1. ホーム
  2. javascript

[解決済み] フラグがtrueになるまで待つ

2022-08-28 02:40:02

質問

javascriptにこのような関数があります。

function myFunction(number) {

    var x=number;
    ...
    ... more initializations
    //here need to wait until flag==true
    while(flag==false)
    {}

    ...
    ... do something

}

問題は、javascriptがwhileでスタックし、私のプログラムが動かなくなることです。そこで質問ですが、"busy-wait"なしでフラグが真になるまで関数の途中で待つにはどうしたらよいですか?

どのように解決するには?

ブラウザのjavascriptはシングルスレッドであり(ここでは関係ないウェブワーカーを除く)、javascript実行の1つのスレッドが完了してから別のスレッドが実行されるので、あなたのステートメントが実行されます。

while(flag==false) {}

は単に永遠に(あるいはブラウザが応答しないjavascriptのループを訴えるまで)実行され、ページはハングしたように見え、他のjavascriptは決して実行する機会を得られません。したがって、フラグの値は決して変更できません。

もう少し説明すると Javascriptはイベント駆動型の言語です。 . つまり、インタプリタに制御を戻すまで、Javascript の一部を実行するのです。 そして、インタプリタに戻ったときだけ、Javascriptはイベントキューから次のイベントを取得し、それを実行します。

タイマーやネットワークイベントなど、あらゆるものがイベントキューを経由して実行されます。 そのため、タイマーが作動したり、ネットワークの要求が来ても、現在実行中のJavascriptを中断させることはありません。 代わりに、イベントがJavascriptのイベントキューに入れられ、現在実行中のJavascriptが終了すると、次のイベントがイベントキューから引き出され、実行する順番が回ってくるのです。

そのため、次のような無限ループを実行する場合 while(flag==false) {} のような無限ループを行うと、現在実行中の Javascript が終了することはなく、イベントキューから次のイベントが引き出されることはなく、したがって flag の値が変更されることはありません。 ここで重要なのは Javascript は割り込み駆動ではありません。 . タイマーが起動したとき、現在実行中のJavascriptを中断して、他のJavascriptを実行し、現在実行中のJavascriptを継続させることはありません。 タイマーはイベントキューに入れられ、現在実行中のJavascriptが終了して実行する番が来るのを待ちます。


あなたがすべきことは、あなたのコードがどのように動作するかを再考し、あなたが実行したいコードを flag 値が変更されたときに実行したいコードをトリガーする別の方法を見つけることです。 Javascript はイベント駆動型の言語として設計されています。 つまり、フラグを変更する可能性のあるイベントをリスニングして、そのイベントでフラグを調べるか、フラグを変更するコードから独自のイベントをトリガーするか、フラグを変更するコードがコールバック関数を実装して、フラグの値を変更するコードの一部がその値を true に変更すると、コールバック関数が呼び出され、 フラグが true に設定されたときに実行したいコードは、適切なタイミングで実行されるようになります。 これは、タイマーのようなものを使ってフラグの値を常にチェックするよりもずっと効率的です。

function codeThatMightChangeFlag(callback) {
    // do a bunch of stuff
    if (condition happens to change flag value) {
        // call the callback to notify other code
        callback();
    }
}