Conceitos Avançados de Frontend: Assincronismo, Armazenamento e Protocolo HTTP

  1. Assincronismo com async/await

O async/await é uma abstração sintática construída sobre Promises, projetada para simplificar a escrita e a leitura de operações assíncronas, conferindo-lhes uma aparência síncrona.

  • O operador await só pode ser utilizado dentro de funções declaradas com a palavra-chave async.
  • Se uma função async não contiver nenhum await, ela ainda retornará uma Promise, mas sua execução interna ocorrerá de forma síncrona.
  • O código subsequente a um await é enfileirado na fila de microssarefas (microtask queue) do Event Loop.
async function processTasks() {
  console.log('Início da execução');
  await Promise.resolve(); // Pausa e cede o controle do thread
  console.log('Execução assíncrona (Microssarefa)');
}

console.log('Script principal');
processTasks();
console.log('Fim do script');

// Ordem de saída: Script principal → Início da execução → Fim do script → Execução assíncrona (Microssarefa)

Interação com Macrotarefas

async function handleTimers() {
  console.log('Passo A');
  await new Promise(resolve => setTimeout(resolve, 0));
  console.log('Passo B (Aguardando Macrotarefa)');
}

handleTimers();
console.log('Passo C');
// Ordem de saída: Passo A → Passo C → Passo B

Tratamento de Erros e Concorrência

Erros em operações assíncronas devem ser capturados utilizando blocos try...catch. Além disso, a execução sequencial de múltiplos await independentes degrada a performance. A otimização é feita através do Promise.all, que executa as Promises em paralelo.

// Abordagem ineficiente (Serial)
async function fetchDataSerial() {
  const profile = await getUserProfile();  // Aguarda a primeira requisição
  const settings = await getUserSettings(); // Só então inicia a segunda
}

// Abordagem otimizada (Paralela)
async function fetchDataParallel() {
  const [profile, settings] = await Promise.all([
    getUserProfile(),
    getUserSettings()
  ]);
}

Atenção: O uso de await dentro de um Array.prototype.forEach não bloqueia a iteração do loop, pois o forEach não foi projetado para lidar com código assíncrono. Prefira loops for...of ou Promise.all combinado com map.

  1. Implementação de Troca Dinâmica de Temas

A alternância de temas na interface (como modo claro e escuro) pode ser implementada manipulando dinamicamente o atributo href de uma tag <link> de folha de estilo.

1. Defina a tag de estilo no HTML:

<link id="active-theme" rel="stylesheet" href="styles/light-mode.css">

2. Crie a lógica de alternância em JavaScript:

function applyTheme(themeName) {
    const stylesheet = document.getElementById('active-theme');
    const themePath = themeName === 'dark' ? 'styles/dark-mode.css' : 'styles/light-mode.css';
    stylesheet.setAttribute('href', themePath);
}

3. Vincule a função aos eventos de interface:

<button onclick="applyTheme('dark')">Ativar Modo Escuro</button>
<button onclick="applyTheme('light')">Ativar Modo Claro</button>

  1. Princípios de Encapsulamento de Componentes

Ao arquiteturar componentes reutilizáveis, é fundamental observar as seguintes práticas:

  • Responsabilidade Única: Cada componente deve possuir um propósito claro, evitando lógica excessiva ou múltiplas responsabilidades.
  • Fluxo de Dados: Utilize propriedades (props) para comunicação descendente (pai para filho) e eventos personalizados para comnuicação ascendente (filho para pai).
  • Flexibilidade de Conteúdo: Empregue slots (ou a propriedade children) para permitir a injeção de marcação externa, aumentando a reutilização.
  • Isolamento de Estilo: Previna vazamentos de CSS utilizando escopo local, como CSS Modules, Styled Components ou Shadow DOM.
  1. Armazenamento Web: localStorage vs sessionStorage

Ambos fazem parte da API Web Storage, mas possuem diferenças arquiteturais cruciais:

  • Ciclo de Vida: O sessionStorage é volátil; seus dados são destruídos assim que a aba ou janela do navegador é fechada. O localStorage persiste indefinidamente no dispositivo do cliente até ser expilcitamente removido.
  • Escopo de Compartilhamento: O sessionStorage é estritamente isolado à aba que o criou. O localStorage é compartilhado entre todas as abas e janelas que acessam a mesma origem.
  • Política de Mesma Origem (Same-Origin): O acesso a ambos os armazenamentos exige que o protocolo, domínio e porta sejam idênticos. Por exemplo, http://exemplo.com:80 não pode acessar dados de https://exemplo.com:80.
  • Capacidade: O sessionStorage geralmente limita-se a 5MB. O localStorage também gira em torno de 5MB a 10MB, variando conforme a implementação do navegador.
  1. Diferenças Fundamentais entre GET e POST

Característica GET POST
Semântica e Propósito Recuperar recursos ou dados (Operações de leitura). Enviar dados para processamento, criação ou modificação.
Idempotência Idempotente (Múltiplas requisições idênticas produzem o mesmo efeito no servidor). Não idempotente (Requisições repetidas podem criar recursos duplicados).
Transmissão de Dados Dados anexados à URL via Query String. Dados encapsulados no Corpo da Requisição (Request Body).
Limites de Tamanho Restrito pelo comprimento máximo da URL suportado pelo navegador/servidor. Praticamente ilimitado (ideal para upload de arquivos ou grandes payloads).
Cache e Histórico Respostas podem ser armazenadas em cache; URLs ficam no histórico do navegador. Respostas não são armazenadas em cache por padrão; não polui o histórico.
Segurança Inadequado para dados sensíveis, pois a URL pode ser exposta em logs ou histórico. Mais seguro por ocultar dados no corpo, mas ainda exige criptografia via HTTPS.

Tags: javascript async-await web-storage http-protocols frontend-architecture

Publicado em 7-17 07:03