Multithreading em JavaScript

Imitando Multithreading em JavaScript

Um evento pró-Driven Architecture é como o cão pedindo (se pudesse), "Quando você vai jogar a bola, quando, hein, quando?" A pseudo-discussão arquitetura é implementada usando timeouts. O pseudo-discussão é o resultado de uma função periódica ou ligue objeto e, a implementação completa é mostrado no seguinte código-fonte.

 Fonte: / cliente / scripts / Jaxson / Common.js função ThreadObject () (this.obj = null; this.data = null; this.intervalId = null; this.isUsed = false;) ThreadObject.prototype.makeCall = function () ( if (typeof (this.obj) == "function") (this.obj (this.data);) else if (typeof (this.obj) == "object") (this.obj.run (this.data );)) = (var Thread threadObjects: new Array () StartThread: function (obj, data, hora) (for (var c1 = 0; c1 <this.threadObjects.length; c1 + +) (if (! presente . threadObjects [C1]. isused) (this.threadObjects [C1]. isused = true; this.threadObjects [C1]. dados = dados; this.threadObjects [C1]. obj = obj; this.threadObjects [C1]. intervalId = window.setInterval ( "Thread.threadObjects [" + c1 + "]. MakeCall ()", tempo); this.threadObjects retorno [C1]. intervalId;)) throw new Error ( "Não foi possível iniciar uma discussão"); endthread), function (intervalId) (for (var c1 = 0; c1 <this.threadObjects.length; c1 + +) (if (this.threadObjects [C1]. intervalId == intervalId) (window.clearInterval (intervalId) ; this.threadObjects [C1]. isused = false;)))) InitializeThreads função (MaxThreads) (for (var c1 = 0; c1 <MaxThreads; c1 + +) (Thread.threadObjects.push (ThreadObject novo ()); )) InitializeThreads (30);

Na origem, dois tipos de objeto são definidos: ThreadObject e Thread. O tipo ThreadObject é usado para gerenciar o segmento de zombar, e gerencia as postagens Thread mock. A função InitializeThreads é usado para configurar o pseudo-threading ambiente. Para explicar este código-fonte, uma abordagem top-down é utilizada.

Quando o arquivo JavaScript que contém o pseudo-arquitetura segmento é carregado, a função InitializeThreads é chamado com um valor de parâmetro de 30. InitializeThreads é usado para inicializar a matriz de pseudo-tópicos que serão chamados. Hard-codificação de um limite de 30 tópicos podem parecer como uma prática de má programação, mas há uma razão para isso. Para criar uma pseudo-discussão, você cria um evento periódico, o que significa que você precisa para usar o window.setInterval ou método window.setTimeout. Chamar um desses métodos requer uma referência de função ou um pedaço de código JavaScript. O problema com ambas as abordagens é que você precisa para serializar o código-fonte. Por exemplo, imagine que você deseja chamar um dos métodos de eventos periódicos com uma inst local objeto de referência, como ilustra o seguinte código fonte:

window.setInterval ( "CallFunction inst ()", 300);
  

A referência a inst no buffer de seqüência de caracteres não terá nenhum significado, porque quando o timer periódico executado, as variáveis locais não estão no contexto. A execução irá resultar em um erro. Outra maneira de chamar a função é para serializar inst para uma reserva, mas que tem a desvantagem de que o Estado sendo usado no evento periódico não será a mesma instância do objeto, assim, se as alterações são feitas entre a convocação da função setInterval e expiração do temporizador, eles não vão estar presentes. O tempo só é válido quando inst inst é se é uma variável global. Como regra geral, a forma mais segura de fazer um método específico de contexto chamada usando o setInterval métodos ou setTimeout é usar uma referência mundial. Uma referência global podem ser criados dinamicamente instanciar variáveis aleatórias ou usando uma matriz de referência do índice. A abordagem escolhida pela linha é o índice da matriz. A função InitializeThreads irá inicializar 30 referências globais de ThreadObject. Cada ThreadObject tem quatro membros de dados:

• obj: referências do objeto a ser executado. O método ThreadObject.makeCall pode distinguir entre uma função e objeto. Se obj é uma função, então obj será chamado usando uma notação de função. Se obj é uma instância do objeto, então o método obj.run é chamado.

• dados: referências dos dados utilizados como um contexto em que obj é executado.

• intervalId: referências o valor retornado pelo método window.setInterval. Esse valor é usado para interromper o evento periódico.

• isused: Usado por Thread para determinar se um índice de matriz é usado atualmente. Quando um novo segmento quer começar, o método StartThread para um índice de vazios, onde isused equivale a um valor de false. Uma vez que um segmento foi iniciado, o membro de dados isused é atribuído um valor de verdade. E quando a discussão tiver terminado a execução, o membro de dados isused é atribuído um valor de false novamente. O pseudo-arquitetura discussão é usado na declaração de DynamicIterator referenciado pelo onmouseover metadados de navegação e eventos onmouseout. Quando você mover o mouse em uma região da página HTML para outra, e outra região tem o evento onmouseover implementadas, o evento é disparado. O evento onmouseover é acionado apenas na primeira vez os movimentos do mouse sobre o evento, e que faz com que o método startIteration a ser chamado, Thread.startThread chamada. Quando o mouse se move para fora da região de navegação de metadados, o método é chamado stopIteration, chamando Thread.endThread. A implementação de startIteration e stopIteration é definida como segue.

 Fonte: / cliente / scripts / Jaxson / uimorphing.js (DynamicIterator)intervalId: 0, startIteration: function (direção) (this.intervalId = Thread.startThread (function (Direc) (DynamicIterator.shiftArrayElements (direcção);), direção, 500);), stopIteration: function () (Thread.endThread ( this.intervalId);)

Colocar as restantes peças do cliente junto

Várias vezes tenho referenciado a execução DynamicIterator, que é usado para navegar nos metadados do conjunto de resultados. O principal papel da DynamicIterator é carregar os elementos de metadados de navegação, e quando os elementos individuais são referenciados, os principais dados é carregado. Eu explico a aplicação da DynamicIterator em pedaços, com a seguinte representação da inicialização dos elementos de navegação.

 Fonte: / cliente / scripts / Jaxson / uimorphing.js var DynamicIterator = (lastElem: null, floatingIframe: null, parentRow: null, initialize: function (floatingIframeID, parentRowID) (this.floatingIframe = document.getElementById (floatingIframeID); this.parentRow = document.getElementById (parentRowID); this.doLayout (); this.getMoreRootElements (0);) doLayout: function () (this.floatingIframe.style.width = document.body.clientWidth - 4; this.floatingIframe.style. height = document.body.clientHeight - 104;), / / Outras declarações ...);

 

Voltando ao início da "Aplicação do HTML secção" Cliente, lembre-se o pedaço de código HTML que implementou o evento body.onload, que chamou a função Initialize local. Na execução de inicializar, o método é chamado DynamicIterator.initialize. Chamando DynamicIterator.initialize será uma referência cruzada de HTML elementos interface do usuário com a instância DynamicIterator.

DynamicIterator.initialize espera dois elementos HTML de interface de usuário: o iframe flutuante (this.floatingIframe) e da linha da tabela (this.parentRow) que contém os elementos de navegação. DynamicIterator necessidades destes dois elementos da interface do usuário, pois carrega os dados em destaque na área de navegação. Depois de os elementos da interface de usuário foram atribuídos aos membros de dados, o método é chamado doLayout. O objetivo do doLayout é redimensionar o iframe para que ele cobre a área cliente apropriado. E a chamada do método passado no DynamicIterator.initialize é a chamada do método getMoreRootElements, que é responsável por carregar os elementos de metadados de navegação. No contexto da DynamicIterator, o método getMoreRootElements é declarada como uma função vazia semelhante ao seguinte:

getMoreRootElements: function (direção) ()

A função é um espaço vazio, e espera-se que o código HTML que irá declarar uma aplicação. No caso do código HTML, getMoreRootElements é definida como segue.

 Fonte: / cliente / artigos ajaxrest / Arquitectura / DynamicIterator.getMoreRootElements dynamiclist.html = função de direção () (if (direction == 0) (var = FactoryHttp.getCachedAsynchronous assíncrona (); asynchronous.settings = (onComplete: function (xmlhttp) (var arrTickers = new Array (); tickers var = JSON.parse (xmlhttp.responseText); for (var c1 = 0; c1 <tickers.length; c1 + +) (arrTickers.push ((text: tickers [c1], url : "/ pyservices / comerciante / histórico / tickers /" + tickers [c1]));) DynamicIterator.associateElements (arrTickers);)) asynchronous.get ( "/ pyservices / comerciante / histórico / tickers");))

No caso do código HTML, os tickers que representam os metadados usados para navegar através da aplicação são carregadas uma única vez. Metadados podem ser ilimitados, mas muitas vezes ele pode ser limitado a um tamanho conjunto fixo, mesmo que o tamanho do conjunto é muito grande. Olhando para o exemplo, cada pedaço de metadados é um relógio que pode ter um a quatro letras (em média). Se você multiplicar esse número por 1.000 tickers, então você tem que baixar cerca de 4KB-5KB de dados (nesta era da banda larga , baixar 4KB-5KB é trivial). A aplicação de ações permitirá que, no máximo, 50 tickers devido a limitações técnicas, para todos os tickers pode ser descarregado em um pedido.

No caso do nosso exemplo, getMoreRootElements com uma direção de 0 significa que o download de um conjunto inicial de elementos de metadados. Como os dados são transferidos é da responsabilidade da execução getMoreRootElements. Este exemplo usa a classe Asynchronous, ea resposta é codificado como uma matriz JSON. Para cada ticker encontrados, um objeto é criado quando o ticker é combinada com uma URL e adicionado à matriz arrTickers. ArrTickers Uma vez que a matriz foi preenchida com os elementos, o DynamicIterator. AssociateElements método é chamado como segue.

 Fonte: / cliente / scripts / Jaxson / uimorphing.js (DynamicIterator)associateElements: function (arrElements) (this.arrElements = arrElements; this.shiftArrayElements (0);)

O método associateElements faz duas coisas: atribui a matriz de referência arrElements e atualiza os dados na página HTML utilizando o método shiftArrayElements. Se o usuário passa o mouse por cima ou seta para a esquerda ou direita, a lista de tickers desloca para a esquerda ou direita.

O movimento do índice está contido dentro do método shiftArrayElements. O autor da chamada do método fornece a direção do deslocamento utilizando um valor positivo ou negativo. Com base no valor direcional, o índice será deslocado. Se o índice transferido vai além dos limites da matriz, em seguida, mais elementos de metadados precisam ser recuperados. A plena implementação da shiftArrayElements é a seguinte.

 Fonte: / cliente / scripts / Jaxson / uimorphing.js (DynamicIterator)shiftArrayElements: function (offset) (this.currOffset = this.currOffset + offset; if (this.currOffset <0) (this.getMoreRootElements (-1); this.currOffset = 0;) else if ((this.currOffset + este . parentRow.cells.length)> = this.arrElements.length) (this.getMoreRootElements (1); this.currOffset = this.arrElements.length - this.parentRow.cells.length;) for (var contador = 1; contador <(this.parentRow.cells.length - 1); contador + +) (this.parentRow.cells [contador]. innerHTML = this.arrElements [this.currOffset + counter - 1]. texto; this.parentRow.cells [ counter]. refElemInfo = this.arrElements [this.currOffset + counter - 1];))

Na execução do shiftArrayElements, um cálculo da mudança requer um teste para determinar se a mudança vai causar um salto para além dos limites da matriz. Se um salto para a esquerda ou à direita da matriz fronteiras acontece, então o método é chamado getMoreRootElements, onde o valor direção -1 ou 1 especifica para prefixo de metadados para o início da matriz ou acrescentar dados ao final da matriz, respectivamente. Se a mudança não provoca um salto para além dos limites da matriz, em seguida, o usuário individual elementos HTML são redesenhadas com a informação nova referência anexada à propriedade refElemInfo. Não é habitual para anexar seus próprios dados a cada um elemento da interface do usuário em HTML, mas neste caso é absolutamente necessário por razões de fazer com que um usuário passar o mouse sobre o elemento.

Se o usuário passa o mouse sobre um ticker, deseja que as informações ticker para ser carregado para a janela do iframe flutuante. Isto é realizado pelo método DynamicIterator.HightlightItem, que é definido como segue.

 Fonte: / cliente / scripts / Jaxson / uimorphing.js (DynamicIterator)highlightItem: function (elem) (if (this.lastElem! = null) (this.shrinkElement (this.lastElem);) this.expandElement (elem); this.lastElem elem =; this.fetch (elem.refElemInfo);) ,

highlightItem não faz nada mais do que delegar as ações para o shrinkElement, expandElement, e buscar métodos. Todos esses métodos são, por padrão funções vazio que a página HTML deve implementar. A idéia de highlightItem é proporcionar um esquema de navegação clickless. Como você faz a função de navegação é de responsabilidade da página HTML. DynamicIterator responsabilidade é a coordenação. Então, o primeiro passo é redimensionar a voltar ao normal o último elemento que foi destaque utilizando o método shrinkElement. No caso do exemplo do relógio, é aplicado da seguinte forma.

 Fonte: / cliente / artigos ajaxrest / Arquitectura / dynamiclist.html DynamicIterator.shrinkElement = function (elem) (elem.style.fontSize = 12;)

A implementação ticker é simples na medida em que diminui a fonte da célula da tabela para 12. Amore Para interface de usuário sofisticada, reduzindo o elemento pode ter significado fechar um menu ou um pop-up elemento div. O próximo passo da highlightItem é destacar o elemento atual usando a função expandElement, que é implementado como se segue.

 Fonte: / cliente / artigos ajaxrest / Arquitectura / dynamiclist.html DynamicIterator.expandElement = function (elem) (elem.style.fontSize = 30; var assíncrono = FactoryHttp.getCachedAsynchronous (); asynchronous.settings = (onComplete: function (xmlhttp) () ) asynchronous.get (elem.refElemInfo.url);)

A implementação expandElement faz duas coisas: aumenta o tamanho da fonte e downloads os dados associados com o elemento de metadados. No entanto, na execução do onComplete, não há nenhuma ação, porque quando você destacar o elemento de metadados, você provavelmente não está interessada em exibir os dados, mas você está interessado em cache os dados para futura referência rápida. Neste ponto, você precisa tomar uma decisão sobre o mecanismo de exibir os dados no iframe. Se você quiser exibir os dados através de um clique, então você precisa implementar onclick para as células individuais da tabela. Se você quiser usar o ato de destaque como o gatilho para mostrar os dados, então você precisa implementar o método onComplete que eu apenas disse que não precisa ser implementada. Meu ponto é que a maneira como você exibir os dados é até você e DynamicIterator define um quadro. DynamicIterator é responsável apenas pela pré-carregamento dos dados. Alguns leitores podem pensar que a recuperação de dados cada vez que um elemento de metadados é destaque é muito caro, mas o custo depende de como você implementou o seu cache. Isto significa que sempre assíncrona é referenciado, a primeira coisa que faz é verificar a cache para a informação. Se a informação estiver disponível, o método onComplete é chamado diretamente. A mágica está no cache, e se não há cache, então toda vez que o elemento de metadados é destaque, os dados associados com o recurso será carregado.

Vamos voltar e pensar sobre a implementação da arquitetura cliente-lado e como se resolve o nosso problema de grandes conjuntos de dados ou lenta. Se estivéssemos trabalhando com uma aplicação de email, em seguida, os metadados seriam os títulos individuais de e-mail, e gostaríamos de iterar sobre os títulos e destacá-los. Para verificar se há novos e-mails, nós podemos "spin off" um segmento que, automaticamente, adicionar elementos de metadados para o final da matriz arrElements. À medida que iterar sobre os títulos de e-mail, o seu conteúdo será baixado e exibido na janela iframe. Agora vamos dizer que fomos cálculo de todos os números primos e queria ver os resultados. Neste caso, os metadados são os dados, e como o aplicativo de email, uma discussão seria desmembrada para manter-se adicionar os resultados para a matriz arrElements. Mencionei esses dois exemplos de tópicos a ser desmembrada, porque, até agora, o exemplo ilustra apenas o expansão e carregamento dos dados quando o usuário pede. Usando JavaScript tópicos, os dados são carregados automaticamente, sem o usuário pedir para ela.

um artigo submetido por Sonja Lande


Isenção de responsabilidade:O nosso site não se responsabiliza pelo conteúdo deste artigo. Webarticles é uma fonte de informação livre.
Importante: Este artigo "Multithreading em JavaScript" foi traduzida por um software automático. Nós sentimos muito por quaisquer erros de ortografia que pode ter ocorrido. Obrigado pela sua compreensão.


Online: 315 users browsing the articles directory