Tag Archives: JavaScript

Currying em Javascript

Uma característica de linguagens funcionais muito usada em Javascript é a técnica de Currying, a grosso modo de explicar, usada para transformar uma função com n argumentos em uma outra função com argumentos simples.

 function pow(i, j) { 
     return i * j;
 }

 function square (k) {
     return pow(k, 2);
 }

 alert(square(6));

Veja nesse exemplo que uma função denominada de pow (que multiplica dois elementos) é usada na função square (que multiplica sempre um elemento por 2) de forma que você tem o uso de primeira pela segunda com uma redução de parâmetros. Essa técnica é usada nas funções de alta ordem como Fold, Map, etc.

Array.prototype.each = function(fn){
	for(var i = 0, len = this.length; i

Exemplo acima usando uma função que aplica outra função para cada elemento de um array.
Essa técnica ficou popular mesmo sendo usada junto a Closure que precisam de funções de callback para processar um resultado de outra função.

Explicando isso em código, teríamos Currying da seguinte forma:

 function atualizar(id) {
     return function(resposta) {
          document.getElementById(id).innerHTML = resposta;
     };
 }

 function processar(msg, fn) {
     fn(msg);
 };

processar('testando currying em ação', atualizar('area'));

Na linha 1, temos a declaração de uma função denominada atualizar que recebe um parâmetro em seu construtor que será o id de um elemento qualquer. A chamada a essa função provoca o retorno de uma outra função declarada internamente na linha 3. Essa função interna recebe também um argumento e a função dela é adicionar esse argumento no conteúdo do elemento passado como parâmetro na função inicial. Criei uma função chamada processar apenas para aplicar uma mensagem a um função, será usada para fazer a mágica do Currying aqui. Veja na linha 15 que usei a função processar para submeter uma frase (primeiro argumento) na função atualizar (segundo argumento), passando para ela o id de um elemento como um DIV.

Observe que esse código é muito comum em frameworks ajax, um exemplo claro disso seria como o DWR trabalha.

 function callback(retorno) {
     alert(retorno);
 }

DWRInterface.metodo(callback);

Aqui aplicamos a função callback na função "metodo" que é um método do objeto DWRInterface controlado pelo framework DWR. DEssa forma quando o DWR processar a requisição ajax, submete o retorno vindo do servidor para a função callback que o recebe como parâmetro.
Vamos investigar outras características de linguagens funcionais nos próximos artigos.

Typically chemist's shop can sale to you with discreet treatments for various soundness problems. There are numerous of safe online pharmacies that will deliver medications to your address. There are divers medicines for each afflictions. Learn more about "viagra manufacturer coupon". Maybe "viagra discount coupons" is a much complicated problem. Matters, like "coupons for viagra", are coupled numerous types of health problems. If you need to take recipe medications, ask your druggist to check your testosterone levels before. Sometimes the treatment options may include erectile disfunction remedies or a suction device that helps get an erection. Keep in mind web-site which is ready to sell erectile disfunction drugs like Viagra without a formula is fraudulent. When you purchase from an unknown web-site, you run the risk of getting counterfeit remedies.

Datas e Fuso horário no Javascript

As operações com datas no javascript sofrem da variação de fuso horário no qual a máquina cliente está configurada.

Certa oportunidade tive que consertar uma função que apresentava diferença entre datas e ninguém sabia o porque. Quando você instancia uma data, o retorno dela aparecerá assim:”Thu Feb 14 2008 08:41:27 GMT-0300 (Hora oficial do Brasil)”.

Observe que na data consta o GMT (Greenwich Mean Time) que indica em que fuso horário a data está configurada.

Vou demonstrar como evitar a diferença de tempo provocada por isso em operações com data. Para isso basta criar uma função que converta a data sempre para o fuso que se espera.

 var calcularFuso = function(data, offset) {

    var milisegundos_com_utc = data.getTime() + (data.getTimezoneOffset() * 60000);
    return new Date(milisegundos_com_utc + (3600000 * offset));

 }

Observe que na linha 3, invocamos o método getTime() que converte o momento local da data para um número representado pelos milisegundos desde 1º de Janeiro de 1970 (Unix Epoch). Obtemos o atual fuso horário que está configurado no browser pelo método getTimezoneOffset() da API de data no javascript e multiplicamos pelos milisegundos de tempo de uma hora. Somamos então os dois valores.

Porque uma hora? Porque esse é o tempo que representa cada fuso horário. Por default esse método retorna esse fuso horário em minutos, por isso a conversão em hora é necessária.

Para chegar nesse número 60000 você tem que lembrar que 1 segundo tem 1000 milisegundos e que 1 minuto tem 60 segundos, então convertendo minutos para milisegundos multiplicamos 60 * 1000 = 60000.

Nesse momento temos o UTC (Coordinated Universal Time) representado pela variável “utc” pela soma do momento local mais o fuso horário local em milisegundos.

Precisamos agora obter uma data a partir desse UTC somado com o fuso horário de destino, como por exemplo uma data expressa no fuso +5 transformado no fuso do Brasil (hora de Brasília) -3.

Observe que na linha 5 que obtemos um offset (representação do fuso) em hora e convertemos para milisegundos. Lembre-se aqui que 1 segundo tem 1000 milisegundos e que 1 hora tem 3600 segundos, portanto converter hora em milisegundo deve-se multiplicar 1000 * 3600 = 3600000.

Somamos esse resultado com o valor da variável “utc” e obtemos o momento para o fuso horável desejado, a partir daí criamos uma nova data com base no long apropriado e retornamos essa nova data.

Dessa forma conseguimos manter a integridade desejada na aplicação quando precisamos expressar a data no fuso horário correto.

Javascript Inline e External

Scripts internos (Inline) ao HTML agilizam em grande parte a exibição porque diminuem o número de requisições HTTP.
Imagine que você tenha uma página com scripts separados:

<script … src=”script1.js”></script>
<script … src=”script2.js”></script>
<script … src=”script3.js”></script>

Nesse caso teremos 3 requisições além da página e sofreremos um aumento de até 50% no tempo de renderização. Isso porque apesar do tamanho dos arquivos serem o mesmo se fossem internos, as múltiplas requisições provocam um overhead.

Ao invés dessa abordagem, se os scripts fossem internos, existiria uma única requisição HTTP e o tempo de renderização seria mais rápido.

O problema na abordagem de scripts internos é que não nos beneficiamos do cache.

Combinando os scripts

Uma alternativa é combinar todos os scripts para forçar apenas uma requisição e se beneficiar do cache.

Aliando a minificação do código, você reduz consideravelmente o tamanho do download do script. Observe que frameworks como o Extjs usam essa técnica, existe um arquivo ext-all.js que combina todos os componentes.

Para páginas que combinam um grande número de componentes e sofrem de elevado “Page Views“, é crucial o cache desses elementos em um único arquivo se beneficiando de poucas requisições HTTP e do uso do cache.

O problema nessa abordagem é que existem regiões com elevado “Page Views” que usam poucos componentes e tem que baixar todo o arquivo de uma só vez.

Download sob demanda

O melhor dos dois mundos é usar a estratégia de “Post-Onload Download” para os casos onde não há necessidade de baixar um script externo com todos os componentes. Nesse caso usamos a estratégia de Script tag e baixamos apenas os módulos necessários a determinada região do sistema. O código do sistema será dividido em módulos.

var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.id = 'ScriptOnDemand';
script.type = 'text/javascript';
script.src = url;
head.appendChild(script);

Lembrando que essa técnica provoca uma aumento não só do esforço no desenvolvimento (porque você terá que administrar as dependências entre os componentes manualmente) como do tempo de manutenção no código (por dividir os scripts em módulos apropriados).

Conclusão

Faça poucas requisições HTTP para uma mesma página. Diminua sempre o número de requisições unindo todos os scripts em um único arquivo.

Caso o arquivo seja grande para uma página, adote a estratégia de subir os arquivos sob demanda.

A recomendação da estratégia adotada vai depender da métrica de cada região do seus sitema e do custo de esforço na administração desse código.

Typically chemist’s shop can sale to you with discreet treatments for various soundness problems. There are numerous of safe online pharmacies that will deliver medications to your address. There are divers medicines for each afflictions. Learn more about “viagra manufacturer coupon“. Maybe “viagra discount coupons” is a very complicated matter. Matters, like “coupons for viagra“, are coupled numerous types of soundness problems. If you need to take prescription medications, ask your pharmacist to check your testosterone levels before. Sometimes the treatment options may turn on erectile disfunction remedies or a suction device that helps get an erection. Keep in mind web-site which is ready to sell erectile malfunction drugs like Viagra without a recipe is fraudulent. When you purchase from an unknown web-site, you run the risk of getting counterfeit remedies.