Podemos considerar um requestAnimFrame um 'rendimento' sobre o ciclo de aplicação para permitir que o ciclo de eventos para o processo?

StackOverflow https://stackoverflow.com//questions/21010396

Pergunta

Eu estou usando o requestAnimFrame método em JavaScript para fazer minha tela de atualização dentro do meu programa de loop principal:

window.requestAnimFrame = (function(callback) {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
})();


function animate() {
    requestAnimationFrame( animate );
//var runcount = 100;
//for (var i=0;i<=100;i++) {
    draw();
//    if (runcount === i)
//        alert("Completed program loop");
//    }
}

O que estava acontecendo era que o meu programa que apenas atualizou o canvas depois da minha loop principal tivesse sido executado 100 iterações e, em seguida, parou.Depois de adicionar o método acima no meu loop principal, de repente, eu recebo atualizações de tela em cada loop do meu programa.

O fato de que a tela não é atualizado até que o meu programa tinha acabado, me fez pensar que a tela de atualização estava em execução em um thread diferente que não tem a prioridade.(Mas nós sabemos que JavaScript é single-threaded).

A minha pergunta é - Podemos considerar um requestAnimFrame um 'rendimento' sobre o ciclo de aplicação para permitir que o ciclo de eventos para o processo? Ainda posso supor que o JavaScript é único thread?

Foi útil?

Solução

Você não são específicos sobre como você fez a sua iteração 1000 vezes, mas eu vou assumir que você significa que você iterada usando um for ou while (loop?me corrija se eu estiver errado...).

Quando você faz um for/while loop, o script será ocupado-loop até que o loop (ou escopo) foi concluída.Como JS é, como você sabe single-threaded que não é possível processar as coisas, tais como a fila de eventos enquanto ele está fazendo isso - para os mesmos, nada será capaz de atualizar (incl.DOM), até o ciclo terminar (geralmente falando, não pode ser específico de navegador de implementação que permitem atualizações do DOM se DOM atualizações são executadas em um thread separado por exemplo, mas isso é uma coisa separada da JS).

Agora que você implementou rAF você está fazendo uma única iteração por quadro.Isso significa que o navegador não tem tempo para processar a fila de eventos de forma assíncrona (não é o mesmo como multi-threaded), a menos que o código que você processados no loop também fez ocupado-loop, por enquanto, o que criaria o mesmo cenário como o primeiro.

Você poderia ter usado setTimeout bem.O que rAF fazer de forma diferente do que, por exemplo setTimeout ou setInterval é que ele é um eficiente e com um baixo nível de implementação de um temporizador mecanismo capaz de sincronizar com o monitor VBLANK período (vertical blanking que a placa de vídeo escravos através de uma opção chamada vsync) - ou seja, na simples palavra de taxa de atualização do monitor (geralmente 60 Hz).Isso nos permite criar regular(er) de animação e é por isso que é chamado de pedido*Animação*Quadro como este é que é principalmente feito.

JS é ainda single-threaded?Sim, isso não vai mudar (a única maneira de alcançar multi-threading em JS é usando Web Trabalhadores).

Fazer rAF mudar alguma coisa?Não nesta área - é uma mais precisas e funcionais alternativa para setTimeout e ele sincroniza de forma diferente, mas isso é tudo.Ele vai sofrer as mesmas restrições, com setTimeout não sendo capaz de disparar se um escopo está ocupado (daí o request* parte do nome o que implica nenhuma garantia), mas quando ele faz disparar vai estar em sincronia com a taxa de atualização do monitor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top