2

setInterval内でコードを実行しているとします。つまり、一連のコードが33ミリ秒ごとに実行され始めます。

この一連のコードの中には関数があります。これをOverlord関数と呼びましょう。この関数は、いくつかの状態変数の値に応じて他の関数を実行します。

質問はこれです:

Overlordがfunction1を実行するとします。function1が33ms(または間隔の長さが何であれ)後に実行を終了していないと仮定します。次に、overlordはfunction1がおそらくまだ実行されている間にfunction2を実行します。何が起こるのですか?

javascriptがfunction2を実行する前にfunction1は終了しますか?javascriptの実行に組み込まれているある種のqueはありますか?

ありがとうございました!

4

3 に答える 3

7

Javascriptはシングルスレッドであるため、2番目の関数はキューに入れられますが、最初の関数の実行が完了するまで実行できません。とはいえ、関数の実行に33ミリ秒以上かかる場合は、関数を小さな非同期チャンクに分割することをお勧めします(インターフェイスのロックを防ぐため)。

于 2013-02-03T05:10:15.020 に答える
2

これはsetIntervalすぐに本当に悪いIDEA ™になることができる場所です。

問題はこれです:

setInterval(lots_O_functions, 15);何が起こるかを呼び出すとlots_O_functions、15ミリ秒後に呼び出されますが、たとえば、すべての作業を完了するのに45ミリ秒かかる場合は、中断されることはなく、代わりにさらに2つのlots_O_functions呼び出しが待機します。あなたの最初のものが終わったらすぐに実行するために...

...これらの2つも1つあたり45ミリ秒かかると仮定すると、さらに6つのlots_O_functions呼び出しが並んで待機しています...

それはあなたがしたいことですか?知らない。個人的には、ほとんどの場合そうではないと思いますが、その理由は次のとおりです。

JSはシングルスレッドで実行されます。実際、VASTのほとんどの場合、ブラウザー内のほとんどすべて(クリック、ページ上の要素の再描画、ページを離れて別の場所に移動することさえ)はすべて同じスレッドに関連付けられています。

そのため、重い関数への呼び出しが重複してスレッドが詰まるのは良くありません

代わりに、次のようなものを用意してみませんか。

var big_state_machine = { /*...*/ },
    lots_O_work = function () {
        big_state_machine.currentState.jobs.forEach(/*...*/);
        /*....... do lots o' work ......*/
        var more_work_to_do = /* figure out if you need to rerun lots_O_work */;

        if (more_work_to_do) { setTimeout(lots_O_work, 20); }
    };


lots_O_work();

これで、必要な処理を実行します。その後、さらに実行する必要がある場合は、setTimeoutを呼び出して、その時点から少なくとも20ミリ秒後に自分自身をキューに入れます。

setTimeoutsleepaやaのようなものではなく、wait「20ミリ秒先を見て、すでに何人の人が何かをするのを待っているかを確認してください... ...そこから始めて、次の利用可能な場所に私を並べてください」と書かれています。

ここでの違いは、最初の関数が終了してから20ミリ秒後に実行されることです。つまり、他の処理(クリック、ペイント、AJAXなど)が発生するまでに少なくとも20ミリ秒かかります。

を使用setIntervalすると、のようになりますが、事後setTimeoutに次の利用可能な場所にキューイングする代わりに、準備ができている(または必要な)かどうかに関係なく、キューに入れられます。

これをさらに分割して、応答性を維持することもできますが、これは良いスタートです。

于 2013-02-03T05:24:39.697 に答える
1

Javascriptはシングルスレッドなので、ほとんどの場合安全です。function1が完了する前にfunction2が実行される唯一の方法は、function1にajax呼び出しや別のsetTimeoutまたはsetIntervalのように終了するコールバックを含む非同期コードがある場合です。例えば:

var setInterval(function(){

    //.. 
    function1();
    function2();

}, 33);

var globalVariable = 0;

var function1 = function(){
    console.log(globalVariable);

    setTimeout(function(){
        globalVariable+=2;
    }, 1000);
};
var function2 = function(){
    console.log(globalVariable);
};

このプログラムの出力は次のようになります。

-> 0

-> 0

-> 2

-> 2

そして、あなたは期待していたかもしれません。

-> 0

-> 2

-> 2

-> 4

于 2013-02-03T05:22:15.847 に答える