Capítulo 3Javascript Conceitos Essenciais

Criado por: Malcon Toledo

Aulas em Vídeo


Down arrow

Parte 1/1

Funções Anônimas

funções anônimas são funções que não dependem de nomes, somente são declaradas.

Funções anônimas



Funções anônimas (com parâmetros)



Para que serve uma função anônima?

Exemplo 1: para executar uma função imediatamente
JS

(function(){
  console.log('exibe logo ao carregar a página')
})()
RESULTADO

Exemplo 2: passar uma função como parâmetro para outra funcão

Closure

Closure é quando uma função é capaz de "lembrar" e acessar seu escopo léxico mesmo quando ela está sendo executada fora de seu escopo léxico.

vamos passo a passo

Escopo Lexico

apenas um ambiente de escopo

JS

let nome = 'Alberto Roberto';
console.log(`nome completo: ${nome}`);
RESULTADO

Exemplo de código contendo apenas um ambiente de escopo

Esse "primeiro nível" é o escopo global

2 ambientes de escopo

JS

let nome = 'Alberto';
function escrever(sobrenome) {
console.log(`nome completo: ${nome} ${sobrenome}`);
}
escrever("Roberto");
RESULTADO

Exemplo de código contendo dois ambientes de escopo

a variável "nome" está no ambiente global

a variável "sobrenome" está no ambiente de escopo da função "escrever"

uma função consegue enxergar as variáveis externas a ela

JS

	function incrementa(){
	  let x = 0;
	  console.log(`x inicial: ${x}`)
	  function adicionaUm(){
		x = x + 1;
	  }
	  adicionaUm()
	  console.log(`x final: ${x}`)
	}
	incrementa()
	incrementa()
	
RESULTADO

as variáveis dentro da função "incrementa" sobrevivem apenas durante sua execução

mas, e se quiséssemos que a função "incrementa" lembrasse do valor de x. Assim a cada chamada, a função funcionaria como uma espécie de contador, sempre incrementando 1 ao valor de x.
é exatamente aqui que entra o conceito de CLOSURE

JS

function incrementa(){
  let x = 0;
  console.log(`x inicial: ${x}`)
  function adicionaUm(){  
    x = x + 1;
    console.log(`x final: ${x}`)
  }
  return adicionaUm
}

let contador = incrementa()
contador()
contador()
	
RESULTADO

A diferença agora é que a função incrementa retorna sua função "filho". Isso faz com que a função filho ainda continue necessária, da mesma forma que as variáveis que ela utiliza (o x no escopo da função pai). Assim, as variáveis não serão destruídas após sua execução, pois elas precisam ficar armazenadas na variável "contador".

reforçando...

CLOSURE é uma forma de fazermos com que as variáves do contexto de uma função persistam e possam ser acessadas mesmo fora do seu contexto léxico estático.

Arrow Functions

sintaxe

Para criar uma arrow function:

  1. os parênteses - que podem ou não ter argumentos
  2. a seta =>
  3. as chaves - que irão conter o código da função

exemplo:

JS

let soma = (a,b) => {
  return a + b
}
console.log (soma(4,6))

RESULTADO

Cuidado: "soma" é o nome da variável e não da função.

Poderíamos ecrever tudo em uma única linha

JS

let soma = (a,b) => { return a + b }
console.log (soma(4,6))

RESULTADO

Se a função vai apenas retornar algum valor, nós podemos omitir as "chaves" e a palavra chave "return"

JS

	let soma = (a,b) => a + b
	console.log (soma(4,6))
	
	
RESULTADO

Programação Síncrona

O começo...

Até um tempo atrás, antes de 2005, a programação web era predominamentemente sincrona.

Programação sincrona

resumidamente, podemos definir programação sincrona quando temos que executar uma operação completamente antes de passar o controle à seguinte

IMPORTANTE

O Javascript é sempre uma linguagem de thread única síncrona (de bloqueio), mas podemos fazer o Javascript agir de forma Assíncrona através da programação

para entedermos o conceito de programação sincrona vamos ao seguinte exemplo:

Façamos um código que:

1)peça o nome do usuário

2)Conte de 1 a 2 bilhões"

4)exiba a data atual

3)exiba a hora atual

5)exiba mensagem de boas vindas

utilizando programação sincrona

JS

let nome = prompt('digite o seu nome');
    
contar();

mostraData()
mostraHora();

console.log("seja bemvindo(a):" + nome)
js

//pesquisar no banco
function contar() {
    let x=1;
    while (x < 2000000000) {
        x++;
    }
}
//mostrar a data
function mostraData(){
    var data = new Date();
    var dia = data.getDate();    // 1-31
    var mes = data.getMonth();   // 0-11 (zero=janeiro)
    var ano = data.getFullYear(); // 4 dígitos
    
    // Formata a data (note o mês + 1)
    var dataAtual = `${dia} / ${mes+1} / ${ano}` 
    
    // Mostra data atual
    console.log('Data atual: ' + dataAtual );
}

//mostrar a hora
function mostraHora(){
    var data = new Date();
    var hora    = data.getHours();    // 0-23
    var min     = data.getMinutes();  // 0-59
    var seg     = data.getSeconds();  // 0-59
    
    var horaAtual = `${hora} : ${min} : ${seg}`;
    // Mostra o resultado
    console.log('Hora atual: ' + horaAtual);
}

Web Work

Muitas vezes iremos precisar trabalhar de forma assincrona no Javascrip.

Web work é uma dessas maneiras

Web Work é, na verdade, um recuro disponibilizado pelo HTML5

Os Web Workers são encadeamentos no navegador que podem ser usados ​​para executar código JavaScript sem bloquear o loop de eventos

Na prática isso permite que longas tarefas possam ser rodadas em segundo plano (multi-threaded)

CUIDADO!!!

Javascript é uma linguagem single thread

Web Work é um recurso do HTML 5, que é executado pelo navegador e que pode ser acessado via javascript

Os Web Workers são executados em um thread isolado no navegador.

Como resultado, o código que eles executam precisa estar contido em um arquivo separado .

para entedermos o conceito de programação sincrona vamos ao seguinte exemplo:

Façamos um código que:

1)Conte de 1 a 3 bilhões"

2)exiba a data atual - (antes que a contagem termine)

index.html

//executa o arquivo em segundo plano com web work - HTML 5
var work = new Worker('script-exemplo.js')

mostraData()

//mostrar a data
function mostraData(){
    var data = new Date();

    var dia = data.getDate();    // 1-31
    var mes = data.getMonth();   // 0-11 (zero=janeiro)
    var ano = data.getFullYear(); // 4 dígitos
    
    // Formata a data (note o mês + 1)
    var dataAtual = `${dia} / ${mes+1} / ${ano}` 
    
    // Mostra data atual
    console.log('Data atual: ' + dataAtual );
}

script-exemplo.js

function contar(inicio, fim) {
    let x=inicio;
    while (x < fim) {
        x++;
    }
    console.log(`contagem finalizada`)
}
contar(1, 300000000)

Enviar mensagem do código principal para o worker

index.html

//carrega o arquivo em segundo plano com web work - HTML 5
var work = new Worker('script-exemplo.js')
//envia mensagem para o worker
work.postMessage([0,10])

mostraData()

//mostrar a data
function mostraData(){
    var data = new Date();

    var dia = data.getDate();    // 1-31
    var mes = data.getMonth();   // 0-11 (zero=janeiro)
    var ano = data.getFullYear(); // 4 dígitos
    
    // Formata a data (note o mês + 1)
    var dataAtual = `${dia} / ${mes+1} / ${ano}` 
    
    // Mostra data atual
    console.log('Data atual: ' + dataAtual );
}
script-exemplo.js

//cria o canal para escutar o envio de mensagens do arquivo principal
addEventListener('message', event => {
    //const [inicio, fim] = event.data;
    let inicio = event.data[0]
    let fim = event.data[1]
    contar(inicio, fim)
});

function contar(inicio, fim) {
    let x=inicio;
    while (x < fim) {
        x++;    
        console.log('x=' + x)

    }
}

Enviar mensagem do worker para o código principal

index.html

//carrega o arquivo em segundo plano com web work - HTML 5
var work = new Worker('script-exemplo.js')

//abre o canal para escutar as mensagens vindas do worker
work.onmessage = function(event){
    mensagem = event.data
    console.log(mensagem)
}

mostraData()

//mostrar a data
function mostraData(){
    var data = new Date();

    var dia = data.getDate();    // 1-31
    var mes = data.getMonth();   // 0-11 (zero=janeiro)
    var ano = data.getFullYear(); // 4 dígitos
    
    // Formata a data (note o mês + 1)
    var dataAtual = `${dia} / ${mes+1} / ${ano}` 
    
    // Mostra data atual
    console.log('Data atual: ' + dataAtual );
}
script-exemplo.js

function contar(inicio, fim) {
    let x=inicio;
    while (x < fim) {
        x++;    
    }
}
contar(1,10);
postMessage("terminou a contagem até 10");

Web Work - Quando utilizar:

- quando precisamos executar algum código demorado dentro do próprio front-end e, ao mesmo tempo, não interferir na interface do usuário.

NOTA: quando o código demorado estiver no back-end a estratégia de usar web worker não é a mais indicada.

Web Work - Quando não utilizar:

- quando o código necessite acessar o DOM

Funções Callback

Métodos Javascript:

setTimeout() setInterval()

Funções Javascript:

map() filter()

Funções Callback são funções que são passadas como parâmetro para outras funções

Exemplo prático 1

Tarefa:

fazer uma função que some ou subtraia dois valores, de acordo com o informado na chamada da função

utilizando o operador IF

JS

let num1 = calcula(4,4,'soma');
console.log (`num1= ${num1}`)

let num2 = calcula(4,4,'subtrai');
console.log (`num1= ${num2}`)


function calcula(a,b,tipoOperacao){
    let resposta
    if (tipoOperacao == "soma") {
        resposta = soma(a,b)
    }
    if (tipoOperacao == "subtrai") {
        resposta = subtrai(a,b)
    }
    return resposta
}
function soma(a, b) {
    return a + b
}
function subtrai(a, b) {
    return a - b
}	
RESULTADO

utilizando Funções Callback

JS

let num1 = calcula(4,4,soma);
console.log (`num1= ${num1}`)

let num2 = calcula(4,4,subtrai);
console.log (`num1= ${num2}`)

function calcula(a,b,tipoOperacao){
    let resposta = tipoOperacao(a,b)
    return resposta
}
function soma(a, b) {
    return a + b
}
function subtrai(a, b) {
    return a - b
}
RESULTADO

método setTimeout()

O método setTimeout() chama uma função ou avalia uma expressão após um número especificado de milissegundos

Exemplo prático 1

JS

console.log('primeira mensagem')

//executa a funcao 'exibaMensagem' após 2000 milisegundos
setTimeout(exibaMensagem, 2000)

console.log('terceira mensagem')

function exibaMensagem(){
    console.log("segunda mensagem")
}
RESULTADO

método setInterval()

O método setTimeout() chama uma função ou avalia uma expressão em intervalos especificados de milissegundos

Exemplo prático

Exibir, a cada segundo, a hora atual no console.

O sistema irá rodar por apenas 5 segundos

JS

let x = 0
 let exibe = setInterval(()=>{
    let data = new Date()
    console.log(data)
    x++
    if (x >= 5) {
        clearInterval(exibe)
    }
 },1000)

A função map()

a função map() irá "aplicar" uma função em cada elemento de um array.

Exemplo pratico

converter uma array contendo valores na escala celsius para a escala Fahrenheit

JS

//array com lista de valores Celsius
let valoresC = [1,20,25,32,40] 
//converte para Fahrenheit
let valoresF = valoresC.map(function(x){
    return (x*9/5)+32;
})
// exibe no console
console.log('Valores convertidos: ' + valoresF)
RESULTADO

A função filter()

a função filter() irá "aplicar" uma condição para cada elemento da matriz. Se a condição for válida o elemento é escolhido.Se for inválida o elemento é deixado de lado

Exemplo pratico

Em uma matriz, selecione os números maiores que 30

JS

//valores originais
let valoresO= [1,32,20,32,40,45,15]
//filtrando...
let valoresF = valoresO.filter(function(x){
    return x>30;
})
//exbibindo no console
console.log('Resultado: ' + valoresF)
RESULTADO

Exemplo prático CALLBACK

1) Fazer uma busca de nomes em um banco, site, etc.... e adicioná-los numa matriz
2) Adicionar o nome "fulano de tal" ao final dessa matriz
3) imprimir toda a matriz


JS

const nomes = [];

//função que busca os nomes 
const buscaNomes = (callBack, nAdd) => {
  setTimeout(() => {
    let matriz = [];
    for (let a = 0; a < 10; a++) {
      nomes.push(`nome${a}`);
    }
    callBack(nAdd);
    console.log(nomes)
  }, 2000);
}

//função que adiona nome
const addNome = (nome) => {
    nomes.push(nome)
}

buscaNomes(addNome, 'fulano de tal');
RESULTADO

Promises

Promise é um objeto que representa a eventual conclusão ou falha de uma operação assincrona

Fonte: MDN

Uma promise é como se fosse uma nota promissória, uma promessa de pagamento

Uma promise irá fornecer uma promessa de um resultdo de código, não irá dar o resultado imediatamente

Exemplo prático PROMISE

1) Fazer uma busca de nomes em um banco, site, etc.... e adicioná-los numa matriz
2) Adicionar o nome "fulano de tal" ao final dessa matriz
3) imprimir toda a matriz


JS

//função que vai fazer alguma coisa...
const buscaNomes = (resolve, reject) => {
  //codigo para buscar nomes
  setTimeout(() => {
    let nomes = []
    for (let a = 0; a < 10; a++) {
      nomes.push(`nome${a}`);
    }
    resolve(nomes)
  }, 2000);
}

//criando a promessa
const consulta = new Promise(buscaNomes)

//solicitando execução da promessa 
consulta.then((result)=>{
  let lista = result
  lista.push('fulano de tal')
  console.log(lista)
})
RESULTADO

Aprofundando

JS

const buscaNomes = (resolve, reject) => {
  //codigo para buscar nomes
  setTimeout(() => {
    let error = false
    
    //simulando erro no processamento
    error = true
    messError = 'algo deu errado'

    if(error) {
      reject(messError)
    } else {
      resolve(result)
    }

  }, 2000);
}

const consulta = new Promise(buscaNomes)

consulta
    .then((result)=>{
      //função que será executada caso tudo corra bem
    })
    .catch((error)=>{
      //função que será executda caso aconteça erro
      console.log(error)
    })
    .finally(()=>{
      //função que será executada dando erro ou não
      console.log('mensagem final ....')
    })
RESULTADO

Asynk/Await

Asynk/Await serve "basicamente" para dar uma melhor legibilidade ao código quando precisamos usar funções assincronas

Exemplo prático Asynk/Await

1) Fazer uma busca de nomes em um banco, site, etc.... e adicioná-los numa matriz
2) Adicionar o nome "fulano de tal" ao final dessa matriz
3) imprimir toda a matriz


JS

function buscarNomes() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let nomes = []
      for (let a = 0; a < 10; a++) {
        nomes.push(`nome${a}`);
      }
      resolve(nomes)
    }, 2000);
  });
}

async function tarefa() {
  let listaNomes = await buscarNomes()
  listaNomes.push('fulano de tal')
  console.log(listaNomes)
}

tarefa()
RESULTADO

Fetch

A API Fetch fornece uma interface JavaScript para acessar e manipular partes do pipeline HTTP, tais como os pedidos e respostas. Ela também fornece o método global fetch() que fornece uma maneira fácil e lógica para buscar recursos de forma assíncrona através da rede

fonte: MDN

Exemplo prático Fech

1) Consulta de cep


JS

const options = {
  method: 'GET',
  mod: 'cors',
  cache: 'default' 
}

fetch(`https://viacep.com.br/ws/01001000/json/`, options)
  .then( response=>{
      let local = response.json()
        .then(data=>{console.log(data)})
    })
  .catch(e=> console.log("erro = " + e.message))
	
RESULTADO