setTimeoutと時間の差

javascript
setTimeoutと時間の差

このようなループがあります

var lastUpdateTime = (new Date()).getTime(),
    diffTime = 0,
    i = 0;

function update() {
    var updateTime = 1000 / 60,
        now;

    // do some stuff...

    console.log("update");
    console.log(" - i:" + i);

    now = (new Date()).getTime();
    diffTime = now - lastUpdateTime;
    lastUpdateTime = now;

    console.log(" - - before diffTime:" + diffTIme);

    while (diffTime >= updateTime) {
        diffTime -= updateTime;
    }

    console.log(" - - after diffTime:" + diffTime);

    updateTime -= diffTime;

    console.log(" - - updateTime:" + updateTime);

    if ( i < 10) {
        i += 1;
        setTimeout(update, updateTime);
    }
}

setTimeoutが呼び出されると、diffTimeの更新時にupdateTimeの間に経過した時間が経過したように見えません。 ここでは、「1000/60」ミリ秒に設定しましたが、それより少ない数値が得られますが、これは意味がありません。 以上である必要があります。 それはなぜそれをしているのですか?

  • davinへの応答:*呼び出しhttp://bonsaiden.github.com/JavaScript-Garden/#other.timeoutsをスタックするため、 `setInterval`は使用しません。

「while」は、特に16ミリ秒を超える場合、diffTimeを「1000/60」時間ブロックに短縮します。 モジュラス演算子は高価です。

「updateTime」が渡されていないことがわかっているのは、「diffTime」を操作する前に出力するからです。 数値は常に、「setTimeout」に指定された「updateTime」よりも小さくなります。

ログ:

update
- i:0
- - before diffTime:1
- - after diffTime:1
- - updateTime:15.666666666666668
update
- i:1
- - before diffTime:12
- - after diffTime:12
- - updateTime:4.666666666666668
update
- i:2
- - before diffTime:54
- - after diffTime:3.999999999999993
- - updateTime:12.666666666666675
update
- i:3
- - before diffTime:13
- - after diffTime:13
- - updateTime:3.666666666666668
update
- i:4
- - before diffTime:11
- - after diffTime:11
- - updateTime:5.666666666666668
update
- i:5
- - before diffTime:14
- - after diffTime:14
- - updateTime:2.666666666666668

「updateTime」と「before diffTime」を見ると、タイミングは意味をなしません。 たとえば、「15.666666666666668」がありますが、それ以降の時間の差は「12」です。

新しいログ:

updateWithoutTimer
- i:0
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668
updateWithoutTimer
- i:1
- - before diffTime:5
- - after diffTime:5
- - updateTime:11.666666666666668
updateWithoutTimer
- i:2
- - before diffTime:8
- - after diffTime:8
- - updateTime:8.666666666666668
updateWithoutTimer
- i:3
- - before diffTime:86
- - after diffTime:2.66666666666665
- - updateTime:14.000000000000018
updateWithoutTimer
- i:4
- - before diffTime:24
- - after diffTime:7.333333333333332
- - updateTime:9.333333333333336
updateWithoutTimer
- i:5
- - before diffTime:34
- - after diffTime:0.6666666666666643
- - updateTime:16.000000000000004
updateWithoutTimer
- i:6
- - before diffTime:24
- - after diffTime:7.333333333333332
- - updateTime:9.333333333333336
updateWithoutTimer
- i:7
- - before diffTime:27
- - after diffTime:10.333333333333332
- - updateTime:6.333333333333336
updateWithoutTimer
- i:8
- - before diffTime:14
- - after diffTime:14
- - updateTime:2.666666666666668
updateWithoutTimer
- i:9
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668
updateWithoutTimer
- i:10
- - before diffTime:2
- - after diffTime:2
- - updateTime:14.666666666666668

最初の目盛りだけでそれを行わない別のログがあります。 私がそれをテストしたとき、それは `setTimeout(func)`のように動作するようですので、ミリ秒は経過しません。 遅延はブラウザのようです。 現在、Mozilla Aurora 6.0aとGoogle Chrome 14.0.803 devを使用しています。 両方のブラウザを再確認するだけで、Auroraでも同じ結果になりますが、Chromeは期待どおりに機能しました。 奇妙なことに、事前にテストしてみましたが、正しく動作しませんでした。 これはAuroraのバグだと思います。 私はmozillaにバグレポートを提出しました。

lastTimeUpdateを割り当てるのは、このフレームに到達するのにかかった時間とフレームにかかった時間を調べたいので、それに応じて処理できるからです。

*更新:*バグレポートはhttps://bugzilla.mozilla.org/show_bug.cgi?id=668765です。 明らかに、 `setTimeout`は正しいことをしようとします。 最近遅く発砲した場合は、早期に発砲しようとします。

  0  0


ベストアンサー

あなたのコードは私にはあまり意味がありません。 「while」ループは何をしているのでしょうか? 丸め後にモジュラス演算子を用意して、1ステップで実行するのはなぜですか? なぜあなたはこのような奇妙な方法でこの差を差し引いていますか? どのような理由で、時間が経過していないと主張しますか? 値の確認は行われていません。

_you_が間隔を次のように設定しているため、もちろん、あなたは ⇐ updateTime = 1000/60〜16`の値を取得しています。 -diffTime。 数学は単純です: 0 <updateTime-diffTime <updateTime

頻繁に更新したいようです。 それが彼らが `setInterval`を発明した理由です。 不要であり、ブラウザの実装よりも信頼性が低いホイールを再発明しています。

更新

あなたはアセンブリプログラマではないと思います。 モジュラス演算子は、4つのワーストケースなど、一定数の算術演算を実行します。 ループは、条件チェック、減算、割り当て、および分岐(それ自体が高価になる可能性がある)を実行する必要があるため、ほぼ同じ数の操作*各反復*を実行します。 したがって、ループが2回の反復を行う場合でも、モジュラス演算子よりもすでに高価です。

あなたの時間に関して、あなたはそれが「いつも」起こると言いますが、その出力からそれはそれが初めてだけ起こるように見えます。 私は同じコードを実行し、数字は理にかなっています。 どのプラットフォームで実行していますか? これは最初のティック以外で起こりますか? 最初のティックで_毎回_発生しますか? もう少し情報が役に立つでしょう。

余談ですが、多くのことを行う前に「lastUpdateTime」を設定しているため、「diffTime」を過大評価しています。 あなたがすべきことは、「setTimeout」の時点で「lastUpdateTime」を割り当てることです。

1


タイトルとURLをコピーしました