revisão de javascript assíncrono

--- id: 6723d35bb07d1bd220d0f28d title: revisão de javascript assíncrono challengeType: 31 dashedName: review-asynchronous-javascript --- # --description--
  • JavaScript Síncrono é executado sequencialmente e espera a operação anterior terminar antes de passar para a próxima.
  • JavaScript Assíncrono permite que múltiplas operações sejam executadas em segundo plano sem bloquear a thread principal.
  • Thread é uma sequência de instruções que pode ser executada independentemente do fluxo principal do programa.
  • Funções callback são funções que são passadas como argumentos para outras funções e são executadas após a conclusão da operação ou como resultado de um evento.

O motor JavaScript e o runtime JavaScript

  • O JavaScript engine é um programa que executa código JavaScript em um navegador web. Ele funciona como um conversor que pega seu código, transforma em instruções que o computador pode entender e agir de acordo.
  • V8 é um exemplo de um motor JavaScript desenvolvido pelo Google.
  • O JavaScript runtime é o ambiente no qual o código JavaScript é executado. Ele inclui o motor JavaScript que processa e executa o código e recursos adicionais como um navegador web ou Node.js.

A API Fetch

  • A Fetch API permite que aplicativos web façam requisições de rede, tipicamente para recuperar ou enviar dados ao servidor. Ela fornece um método fetch() que você pode usar para fazer essas requisições.
  • Você pode recuperar texto, imagens, áudio, JSON e outros tipos de dados usando a Fetch API.

Métodos HTTP para a Fetch API

A Fetch API suporta vários métodos HTTP para interagir com o servidor. Os métodos mais comuns são:
  • GET: Usado para recuperar dados do servidor. Por padrão, a Fetch API usa o método GET para recuperar dados.
fetch('https://api.example.com/data')
Para usar os dados obtidos, eles devem ser convertidos para o formato JSON usando o método .json():
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
Neste código, fetch() retorna uma Promise, e o manipulador .then() está convertendo a resposta resolvida para o formato JSON.
  • POST: Usado para enviar dados ao servidor. O método POST é usado para criar novos recursos no servidor.
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  })
})
Neste exemplo, estamos enviando uma requisição POST para criar um novo usuário. Especificamos o método como POST, definimos os cabeçalhos apropriados e incluímos um corpo com os dados que queremos enviar. O corpo precisa ser uma string, então usamos JSON.stringify() para converter nosso objeto em uma string JSON.
  • PUT: Usado para atualizar dados no servidor. O método PUT é usado para atualizar recursos existentes no servidor.
fetch('https://api.example.com/users/45', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Smith',
    email: 'john@example.com'
  })
})
Neste exemplo, estamos atualizando o ID 45 que está especificado no final da URL. Usamos o método PUT no código e também especificamos os dados como o corpo que será usado para atualizar os dados identificados.
  • DELETE: Usado para deletar dados no servidor. O método DELETE é usado para deletar recursos no servidor.
fetch('https://api.example.com/users/45', {
  method: 'DELETE'
})
Neste exemplo, estamos enviando uma requisição DELETE para remover um usuário com o ID 45.

Promise e encadeamento de promise

  • Promises são objetos que representam a conclusão eventual ou falha de uma operação assíncrona e seu valor resultante. O valor da promise é conhecido somente quando a operação assíncrona é concluída.
  • Aqui está um exemplo para criar uma promise simples:
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Data received successfully');
  }, 2000);
});
  • O método .then() é usado em uma Promise para especificar o que deve acontecer quando a Promise é resolvida, enquanto .catch() é usado para tratar quaisquer erros que ocorram.
  • Aqui está um exemplo de uso de .then() e .catch() com uma Promise:
promise
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });
No exemplo acima, o método .then() é usado para registrar os dados recebidos da Promise, enquanto o método .catch() é usado para registrar quaisquer erros que ocorram.
  • Encadeamento de Promise: Uma das funcionalidades poderosas das Promises é que podemos encadear múltiplas operações assíncronas juntas. Cada .then() pode retornar uma nova Promise, permitindo que você execute uma sequência de operações assíncronas uma após a outra.
  • Aqui está um exemplo de encadeamento de Promise:
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
    return fetch('https://api.example.com/other-data');
  })
  .then(response => response.json())
  .then(otherData => {
    console.log(otherData);
  })
  .catch(error => {
    console.error(error);
  });
No exemplo acima, primeiro buscamos dados de uma URL, depois buscamos dados de outra URL com base na primeira resposta e finalmente registramos o segundo dado recebido. O método catch lidaria com quaisquer erros que ocorram durante o processo. Isso significa que você não precisa adicionar tratamento de erros em cada etapa, o que pode simplificar muito o seu código.

Usando async/await para lidar com promises

async/await facilita a escrita e a leitura de código assíncrono que é construído sobre Promises.
  • async: A palavra-chave async é usada para definir uma função assíncrona. Uma função async retorna uma Promise, que é resolvida com o valor retornado pela função async.
  • await: A palavra-chave await é usada dentro de uma função async para pausar a execução da função até que a Promise seja resolvida. Ela só pode ser usada dentro de uma função async.
  • Aqui está um exemplo de uso de async/await:
async function delayedGreeting(name) {
  console.log("A Messenger entered the chat...");
  await new Promise(resolve => setTimeout(resolve, 2000));
  console.log(Hello, ${name}!);
}

delayedGreeting("Alice");
console.log("First Printed Message!");
No exemplo acima, a função delayedGreeting é uma função async que pausa por 2 segundos antes de imprimir a mensagem de saudação. A palavra-chave await é usada para pausar a execução da função até que a Promise seja resolvida.
  • Uma das maiores vantagens do async/await é o tratamento de erros via blocos try/catch. Aqui está um exemplo:
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

fetchData();
No exemplo acima, o bloco try contém o código que pode gerar um erro e o bloco catch trata o erro caso ele ocorra. Isso torna o tratamento de erros mais direto e legível.

O atributo async

  • O atributo async informa ao navegador para baixar o arquivo de script de forma assíncrona enquanto continua a analisar o documento HTML.
  • Uma vez que o script é baixado, o parsing do HTML é pausado, o script é executado e então o parsing do HTML é retomado.
  • Você deve usar async para scripts independentes onde a ordem de execução não importa.

O atributo defer

  • O atributo defer também baixa o script de forma assíncrona, mas adia a execução do script até que o documento HTML tenha sido totalmente analisado.
  • Os scripts defer mantêm a ordem de execução conforme aparecem no documento HTML.
  • É importante notar que os atributos async e defer são ignorados para scripts inline e funcionam apenas para arquivos de script externos.
  • Quando os atributos async e defer estão presentes, o atributo async tem precedência.

API de Geolocalização

  • A API de Geolocalização fornece uma maneira para os sites solicitarem a localização do usuário.
  • O exemplo abaixo demonstra o método getCurrentPosition() da API que é usado para obter a localização atual do usuário.
navigator.geolocation.getCurrentPosition(
  (position) => {
    console.log("Latitude: " + position.coords.latitude);
    console.log("Longitude: " + position.coords.longitude);
  },
  (error) => {
    console.log("Error: " + error.message);
  }
);
Neste código, estamos chamando getCurrentPosition e passando uma função que será chamada quando a posição for obtida com sucesso. O objeto position contém uma variedade de informações, mas aqui selecionamos apenas latitude e longitude. Se houver um problema ao obter o position, o erro será registrado no console.
  • É importante respeitar a privacidade do usuário e solicitar a localização dele somente quando necessário.
# --assignment-- Revise os tópicos e conceitos de JavaScript Assíncrono.