1

javascriptにスリープ関数オブジェクトがあります-

    function sleep(ms) { 
        var d = new Date(); 
        var target=d.getTime()+ms; 
        var next = d; 
        console.log('Slept');
        while(next.getTime()<=target) {
            next=new Date(); 
        }
        console.log('Woke Up');
        return;
    }

これを使用sleep(5000)すると(コンソールで)印刷されます

Slept

そして5秒後

Woke Up

このコードも正常に機能します-alert('foo'); sleep(5000); alert('bar'); 最初fooと5秒後bar

しかし、この機能は

//ctx is a 2d context of a canvas
function go() {
    ctx.fillRect(100,100,200,200); 
    sleep(1000); 
    ctx.fillRect(200,200,300,300); 
    sleep(1000);
    ctx.fillRect(300,300,400,400); 
    sleep(1000);
    ctx.fillRect(400,400,500,500);
}

go();

動かない。私はそれが機能していることを意味しますが、それが本来あるべき方法ではありません。最初にコンソールに表示されます-

Slept
//1 second later
Woke Up  
//1 second later  
Slept
//1 second later
Woke Up
Slept
//1 second later
Woke Up

そして、これらすべてのメッセージが印刷された後、図(長方形)がキャンバスに描かれます。またはを使用せずにこれを行う方法はありますsetTimeoutsetInterval

質問-関数が機能しfillRectないのはなぜsleepですか?setTimeoutそして、とを使用せずにjavascriptの一部のコードを遅らせる方法はありsetIntervalますか?

4

2 に答える 2

2

sleep()関数を非同期として実装する必要があります(つまり、setTimeout()またはsetInterval())。あなたがそれをしたように、それはレンダリングやペイントなどのブラウザのすべてのアクションをブロックしています。コントロールをブラウザに戻した後でのみ、長方形が描画されます。

于 2013-03-06T07:36:51.937 に答える
1

「またはを使用せずにこれを行う方法はありますsetTimeoutsetInterval」いいえ、そうではありません。各ステップを非同期にする必要があり、タイマーはそれです。

sleep(...)問題は、実行されている限り、UIスレッドをブロックしていることです。それが再び無料になるまで、ブラウザは描画している図形で表示を更新できません。

実行に1ミリ秒の休憩を与えるだけでも、ステップ間で更新するのに十分な時間が与えられます。

function go() {
    ctx.fillRect(100,100,200,200);
    sleep(1000);
    ctx.fillRect(200,200,300,300);
    sleep(1000);
    setTimeout(function () {
        ctx.fillRect(300,300,400,400);
        sleep(1000);
        ctx.fillRect(400,400,500,500);
    }, 1);
}
于 2013-03-06T07:37:53.053 に答える