É uma decisão deliberada de design ou um problema com nossos navegadores atuais que serão corrigidos nas próximas versões?
É uma decisão deliberada de design ou um problema com nossos navegadores atuais que serão corrigidos nas próximas versões?
Respostas:
O JavaScript não suporta multiencadeamento porque o interpretador JavaScript no navegador é um encadeamento único (AFAIK). Mesmo o Google Chrome não permitirá que o JavaScript de uma única página da web seja executado simultaneamente, pois isso causaria grandes problemas de simultaneidade nas páginas da web existentes. Tudo o que o Chrome faz é separar vários componentes (guias diferentes, plug-ins, etc.) em processos separados, mas não consigo imaginar uma única página com mais de um encadeamento JavaScript.
No entanto, você pode usar, como sugerido, setTimeout
para permitir algum tipo de agendamento e simultaneidade "falsa". Isso faz com que o navegador recupere o controle do encadeamento de renderização e inicie o código JavaScript fornecido setTimeout
após o número especificado de milissegundos. Isso é muito útil se você deseja permitir que a viewport (o que você vê) seja atualizada enquanto executa operações nela. Apenas percorrer, por exemplo, as coordenadas e atualizar um elemento de acordo, permitirá que você veja as posições inicial e final, e nada no meio.
Usamos uma biblioteca de abstração em JavaScript que nos permite criar processos e threads que são todos gerenciados pelo mesmo intérprete de JavaScript. Isso nos permite executar ações da seguinte maneira:
Isso permite alguma forma de programação e paralelismo de falsificações, início e parada de threads, etc., mas não será verdadeiro multi-threading. Eu acho que nunca será implementado no próprio idioma, já que o verdadeiro multithread é útil apenas se o navegador puder executar uma única página com vários threads (ou até mais de um núcleo), e as dificuldades são muito maiores. do que as possibilidades extras.
Para o futuro do JavaScript, confira: https://developer.mozilla.org/presentations/xtech2006/javascript/
O multi-threading JavaScript (com algumas limitações) está aqui. Trabalhadores implementados pelo Google para o Gears, e os trabalhadores estão sendo incluídos no HTML5. A maioria dos navegadores já adicionou suporte para esse recurso.
A segurança do encadeamento de dados é garantida porque todos os dados comunicados ao / do trabalhador são serializados / copiados.
Para mais informações, leia:
Tradicionalmente, o JS era destinado a trechos de código curtos e de execução rápida. Se você tinha grandes cálculos em andamento, fazia isso em um servidor - a idéia de um aplicativo JS + HTML que era executado no seu navegador por longos períodos de tempo fazendo coisas não triviais era absurda.
Claro, agora temos isso. Mas demorará um pouco para os navegadores se atualizarem - a maioria deles foi projetada em torno de um modelo de thread único, e mudar isso não é fácil. O Google Gears evita muitos problemas em potencial, exigindo que a execução em segundo plano seja isolada - sem alterar o DOM (já que isso não é seguro para threads), sem acessar objetos criados pelo thread principal (idem). Embora restritivo, esse provavelmente será o design mais prático para o futuro próximo, porque simplifica o design do navegador e reduz o risco de permitir que codificadores JS inexperientes mexam com os threads ...
@marcio :
Por que esse é um motivo para não implementar multi-threading em Javascript? Os programadores podem fazer o que quiserem com as ferramentas que possuem.
Portanto, não vamos dar a eles ferramentas tão fáceis de usar mal que todos os outros sites que eu abro acabam travando meu navegador. Uma implementação ingênua disso o levaria direto ao território que causou tantas dores de cabeça ao MS durante o desenvolvimento do IE7: autores de complementos foram rápidos e frouxos com o modelo de encadeamento, resultando em erros ocultos que se tornaram evidentes quando os ciclos de vida do objeto foram alterados no encadeamento primário . RUIM. Se você está escrevendo complementos ActiveX multithread para o IE, acho que ele vem com o território; não significa que precisa ir além disso.
Não sei a lógica dessa decisão, mas sei que você pode simular alguns dos benefícios da programação multiencadeada usando setTimeout. Você pode dar a ilusão de vários processos fazendo coisas ao mesmo tempo, embora, na realidade, tudo aconteça em um único segmento.
Faça com que sua função faça um pouco de trabalho e chame algo como:
setTimeout(function () {
... do the rest of the work...
}, 0);
E qualquer outra coisa que precise ser feita (como atualizações da interface do usuário, imagens animadas etc.) acontecerá quando tiverem uma chance.
loop
dentro do, setTimeout
mas aparentemente isso não funciona. Você já fez algo assim ou tem um hack? um exemplo seria para uma matriz de 1000 elementos, espero usar dois para loops dentro de duas setTimeout
chamadas, de modo que o primeiro faça um loop e imprima o elemento 0..499
, o segundo faça um loop e imprima o elemento 500..999
.
Você quer dizer por que o idioma não suporta multithreading ou por que os mecanismos JavaScript nos navegadores não suportam multithreading?
A resposta para a primeira pergunta é que o JavaScript no navegador deve ser executado em uma sandbox e de maneira independente da máquina / sistema operacional; adicionar suporte a multithreading complicaria o idioma e amarraria o idioma muito próximo ao sistema operacional.
O Node.js 10.5+ suporta threads de trabalho como recurso experimental (você pode usá-lo com o sinalizador --experimental-worker ativado): https://nodejs.org/api/worker_threads.html
Então, a regra é:
Os encadeamentos de trabalho devem ser de longa duração, o que significa que você gera um encadeamento em segundo plano e depois se comunica com ele por meio da passagem de mensagens.
Caso contrário, se você precisar executar uma carga pesada da CPU com uma função anônima, poderá acessar https://github.com/wilk/microjob , uma pequena biblioteca criada em torno de threads de trabalho.
Assim como matt b disse, a questão não é muito clara. Supondo que você esteja perguntando sobre o suporte a multithreading no idioma: porque não é necessário para 99,999% dos aplicativos em execução no navegador atualmente. Se você realmente precisar, existem soluções alternativas (como usar window.setTimeout).
Em geral, o multithreading é muito, muito, muito, muito, muito, muito difícil (eu disse que é difícil?) Acertar, a menos que você faça restrições extras (como usar apenas dados imutáveis).
A Intel vem fazendo uma pesquisa de código aberto sobre multithreading em Javascript, que foi exibida recentemente no GDC 2012. Aqui está o link para o vídeo . O grupo de pesquisa usou o OpenCL, que se concentra principalmente nos chipsets Intel e no Windows OS. O projeto é nomeado como RiverTrail e o código está disponível no GitHub
Alguns links mais úteis:
Construindo uma estrada de computação para aplicativos da Web
Atualmente, alguns navegadores suportam multithreading. Portanto, se você precisar, poderá usar bibliotecas específicas. Por exemplo, veja os próximos materiais:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (suporte a threads em segundo plano);
https://keithwhor.github.io/multithread.js/ (a biblioteca).
São as implementações que não suportam multi-threading. Atualmente, o Google Gears está fornecendo uma maneira de usar alguma forma de simultaneidade executando processos externos, mas é isso.
O novo navegador que o Google deve lançar hoje (Google Chrome) executa algum código em paralelo, separando-o em processo.
A linguagem principal, é claro, pode ter o mesmo suporte que, digamos, Java, mas o suporte a algo como a simultaneidade de Erlang não está nem perto do horizonte.
Javascript é uma linguagem de thread único. Isso significa que ele possui uma pilha de chamadas e um monte de memória. Como esperado, ele executa o código em ordem e deve concluir a execução de um código de peça antes de passar para o próximo. É síncrono, mas às vezes isso pode ser prejudicial. Por exemplo, se uma função demora um pouco para ser executada ou precisa esperar algo, ela congela tudo enquanto isso.
Sem o suporte adequado ao idioma para sincronização de encadeamentos, nem faz sentido tentar novas implementações. Aplicativos JS complexos existentes (por exemplo, qualquer coisa usando o ExtJS) provavelmente travariam inesperadamente, mas sem uma synchronized
palavra - chave ou algo semelhante, também seria muito difícil ou até impossível escrever novos programas que se comportassem corretamente.
No entanto, você pode usar a função eval para trazer simultaneidade PARA ALGUM MOMENTO
/* content of the threads to be run */
var threads = [
[
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');"
],
[
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');"
]
];
window.onload = function() {
var lines = 0, quantum = 3, max = 0;
/* get the longer thread length */
for(var i=0; i<threads.length; i++) {
if(max < threads[i].length) {
max = threads[i].length;
}
}
/* execute them */
while(lines < max) {
for(var i=0; i<threads.length; i++) {
for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
eval(threads[i][j]);
}
}
lines += quantum;
}
}
É claramente possível realizar multi-threading com javascript usando os trabalhadores da Web trazidos pelo HTML5.
A principal diferença entre os trabalhadores da Web e um ambiente multithread padrão é que os recursos de memória não são compartilhados com o encadeamento principal, uma referência a um objeto não é visível de um encadeamento para outro. Os encadeamentos se comunicam através da troca de mensagens; portanto, é possível implementar um algoritmo de sincronização e chamada de método simultâneo seguindo um padrão de design orientado a eventos.
Existem muitas estruturas que permitem estruturar a programação entre threads, entre elas o OODK-JS, uma estrutura OOP js que suporta programação simultânea https://github.com/GOMServices/oodk-js-oop-for-js