Prévia do material em texto
Desenvolvimento Web 1 – Jair C Leite
DESENVOLVIMENTO
DE SISTEMAS WEB 1
Jair C Leite
Desenvolvimento Web 1 – Jair C Leite
Programação Assíncrona
em JS
Callbacks, Promise, Async, Fetch
Desenvolvimento Web 1 – Jair C Leite
Objetivo da aula
Entender o funcionamento de JS em funções assíncronas,
utilizando algumas técnicas e APIs (objetos) existentes na
linguagem.
• Revisão: arrow function
• Programação baseada em eventos
• Callbacks
• Promises
• Async / await
• Fetch
Desenvolvimento Web 1 – Jair C Leite
Definição e uso de funções
• Em JS, em bastante comum armazenar em variável a
definição da função (texto que descreve a função)
• Da mesma forma, é comum passar essa definição da função
como parâmetro
• O uso (execução) da função quanto ela está acompanhada
do operador de invocação
• myCalculator = function(num1, num2) {
result num1 + num2;
}
• myCalculator é uma variável que contém a definição e pode
ser passada como parâmetro
• myDisplayer(myCalculator) //a definição de função é passada
• myDisplayer(myCalculator(12,34)) // o resultado é passado
Desenvolvimento Web 1 – Jair C Leite
Funções Seta => (Arrow function)
• Uma função
• var m = function(x, y) {
return x * y;
}
• pode alternativamente ser escrita assim
• const m = (x, y) => x * y;
• Com apenas um argumento, o parêntese pode sair
• const m = x => x*2;
• Observações
• Precisam ser definidas antes de usar
• Deve-ser usar const no lugar de var
Desenvolvimento Web 1 – Jair C Leite
Programação assíncrona - por que?
• Programas, em geral, executam instruções seguindo
um fluxo de controle definido no programa.
• Em alguma situações, a execução de uma instrução
pode ser demora e o programa poderia estar
executando outras instrução.
• Por exemplo, um acesso a um arquivo ou BD para procurar um
dado, pode levar alguns minutos
• Ou uma requisição do frontend para o backend pode ter uma
resposta muito longa
• Seria interessante que o programa não ficasse parado,
esperando pela resposta
Desenvolvimento Web 1 – Jair C Leite
Programação assíncrona
• Programas JS são interpretados e rodam em motores
no browser (frontend) ou NodeJS (backend)
• A execução ocorre em um único fluxo de controle
(thread)
• No entanto, a linguagem oferece mecanismos para
contornar
• Programação baseada em eventos e Callbacks
• No browser: onclick, onload, onmouseover, etc..)
• No NodeJS: event API (event.on, etc.)
• AJAX, Promise, Async /await, Fetch
• São comandos ou APIs para facilitar a programação
http://event.on
Desenvolvimento Web 1 – Jair C Leite
Callback
• Uma função pode ser passada como argumento para
outra função para ser chamada de volta mais tarde
• Muito usado em programação assíncrona e dirigida por
eventos
• Exemplo simples:
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
function myCalculator(num1, num2, myCallback) {
let sum = num1 + num2;
myCallback(sum);
}
myCalculator(5, 5, myDisplayer);
Desenvolvimento Web 1 – Jair C Leite
JS Assíncrono
• Em programação assíncrona, uma função pode ser
passada para outra que a chama de volta (callback)
quando ocorre um evento
• Exemplo, a cada 1 segundo, setInterval chama de volta
myFunction:
setInterval(myFunction, 1000);
function myFunction() {
let d = new Date();
document.getElementById("demo").innerHTML=
d.getHours() + ":" +
d.getMinutes() + ":" +
d.getSeconds();
}
Desenvolvimento Web 1 – Jair C Leite
JS Assíncrono com AJAX
• exemplo:
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
function getFile(myCallback) {
let req = new XMLHttpRequest();
req.open('GET', "mycar.html");
req.onload = function() {
if (req.status == 200) {
myCallback(this.responseText);
} else {
myCallback("Error: " + req.status);
}
}
req.send();
}
getFile(myDisplayer);
Desenvolvimento Web 1 – Jair C Leite
Promises
Desenvolvimento Web 1 – Jair C Leite
O que são Promises?
• Representam um valor que pode estar disponível
agora, no futuro ou nunca.
• Promises podem estar em três estados:
• pendente (pending),
• resolvida (fulfilled) e
• rejeitada (rejected).
Desenvolvimento Web 1 – Jair C Leite
JS Promises
• Promise é um objeto JS que liga um código que gera
uma saída a um outro que consome esse resultado
let myPromise = new Promise(function(myResolve, myReject) {
myResolve(); // se sucesso
myReject(); // se erro
});
myPromise.then(
function(value) { /* executa se sucesso */ },
function(error) { /* executa se erro*/ }
);
Desenvolvimento Web 1 – Jair C Leite
JS Promises
• Exemplo function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
let myPromise = new Promise(function(myResolve, myReject) {
let x = 1;
if (x == 0) {
myResolve("OK");
} else {
myReject("Error");
}
});
myPromise.then(
function(value) {myDisplayer(value);},
function(error) {myDisplayer(error);}
);
Desenvolvimento Web 1 – Jair C Leite
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
let myPromise = new Promise(function(myResolve, myReject) {
let x = 0;
if (x == 0) {
myResolve("OK");
} else {
myReject("Error");
}
});
myPromise.then(
function(value) {myDisplayer(value);},
function(error) {myDisplayer(error);}
);
resolvendo
fazendo a
promessa
resolução
prometida
rejeição
prometida
se rejeitado
se resolvido
quando resolvido
(sucesso tem valor)
Desenvolvimento Web 1 – Jair C Leite
Padrão de notação mais claro
A versão anterior não usa .catch para indicar mais
claramente quando a promessa é resolvida.
Assim, o próximo slide indica melhor quando a promise é
rejeitada
Desenvolvimento Web 1 – Jair C Leite
let minhaPromise = new Promise((resolve, reject) => {
let sucesso = true; // ou false
if (sucesso) {
resolve('Promise resolvida com sucesso!');
} else {
reject('Falha ao resolver a Promise.');
}
});
// Consumindo a Promise
minhaPromise
.then(mensagem => {
console.log(mensagem);
})
.catch(erro => {
console.error(erro);
});
resolvendo
fazendo a
promessa
resolução
prometida
rejeição
prometida
se rejeitado
faça catch
se resolvido
faça then
quando resolvido
(sucesso tem valor)
Desenvolvimento Web 1 – Jair C Leite
Desenvolvimento Web 1 – Jair C Leite
Atenção com a sintaxe
Observe nesta versão alternativa (não comum e não
recomendada) que fica claro entender os parâmetros da
promise:
const promiseDef = function(myResolve, myReject) {
let x = 0;
if (x == 0) {
myResolve("OK");
} else {
myReject("Error");
}
}
const success = function(value) {myDisplayer(value);}
const fail = function(error) {myDisplayer(error);}
let myPromise = new Promise(promiseDef);
myPromise.then(success,fail);
Desenvolvimento Web 1 – Jair C Leite
Usando arrow functions
Observe nesta versão alternativa (não comum e não
recomendada) que fica claro entender os parâmetros da
promise:
const promiseDef = (myResolve, myReject) => {
let x = 0;
if (x == 0) {
myResolve("OK");
} else {
myReject("Error");
}
}
const success = (value) => {myDisplayer(value);}
const fail = (error) => {myDisplayer(error);}
let myPromise = new Promise(promiseDef);
myPromise.then(success,fail);
Desenvolvimento Web 1 – Jair C Leite
Encadeamento de Promise
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000); // resolve após 1 segundo
});
promise
.then(result => {
console.log(result); // 1
return result * 2;
})
.then(result => {
console.log(result); // 2
return result * 3;
})
.then(result => {
console.log(result); // 6
})
.catch(error => {
console.error('Erro:', error);
});
● A Promise inicial é resolvida com 2 após 1
segundo.
● O primeiro .then() recebe esse 2, imprime, e
retorna 2 * 2 = 4.
● O segundo .then() recebe 4, imprime, e retorna 4 *
3 = 12.
● O terceiro .then() recebe 12 e imprime.
● Cada .then() esperaa execução do anterior
terminar, mesmo que as operações sejam
assíncronas.
Desenvolvimento Web 1 – Jair C Leite
AJAX com Promise
Desenvolvimento Web 1 – Jair C Leite
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
let myPromise = new Promise(function(myResolve, myReject) {
let req = new XMLHttpRequest();
req.open('GET', "mycar.html");
req.onload = function() {
if (req.status == 200) {
myResolve(req.response);
} else {
myReject("File not Found");
}
};
req.send();
});
myPromise.then(
function(value) {myDisplayer(value);},
function(error) {myDisplayer(error);}
);
Desenvolvimento Web 1 – Jair C Leite
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
function myAjax(myResolve, myReject) {
let req = new XMLHttpRequest();
req.open('GET', "mycar.html");
req.onload = function() {
if (req.status == 200) {
myResolve(req.response);
} else {
myReject("File not Found");
}
};
req.send();
}
function value(v) {
myDisplayer(v)
};
function error(e) {
myDisplayer(e)
};
let myPromise = new Promise(myAjax);
myPromise.then(value,error);
Desenvolvimento Web 1 – Jair C Leite
Async / await
Desenvolvimento Web 1 – Jair C Leite
Async / await
• Funções Async são abstrações construídas sobre
Promises
• O async indica que a função retorna a promise
• Opcionalmente, o reject pode não ser necessário
async function myDisplay() {
let myPromise = new Promise(function(resolve, reject) {
resolve("I love You !!");
});
document.getElementById("demo").innerHTML = await myPromise;
}
myDisplay();
Desenvolvimento Web 1 – Jair C Leite
Usando async com AJAX
O uso de async /await organiza e simplifica o uso de
Promise
async function getFile() {
let myPromise = new Promise(function(resolve) {
let req = new XMLHttpRequest();
req.open('GET', "mycar.html");
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
} else {
resolve("File not Found");
}
};
req.send();
});
document.getElementById("demo").innerHTML = await myPromise;
}
getFile();
Desenvolvimento Web 1 – Jair C Leite
Fetch API
Desenvolvimento Web 1 – Jair C Leite
Realizando uma requisição GET
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(data => {
console.log('GET Request Data:', data);
})
.catch(error => {
console.error('Error:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Lidando com respostas
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
console.log('Response Data:', data);
})
.catch(error => {
console.error('Fetch error:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Realizando uma requisição POST
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1,
}),
})
.then(response => response.json())
.then(data => {
console.log('POST Request Data:', data);
})
.catch(error => {
console.error('Error:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Tratamento de erros
fetch('https://api.invalidurl.com/data')
.then(response => {
if (!response.ok) {
throw new Error('HTTP error! status: ' + response.status);
}
return response.json();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Exercícios
• Exercício 1: Realizar uma requisição GET para obter uma lista de
posts de uma API pública e exibir no console.
• Exercício 2: Realizar uma requisição POST para enviar dados para
uma API pública e exibir a resposta no console.
• Exercício 3: Manipular e exibir os erros corretamente no console.
Sugestão de API https://jsonplaceholder.typicode.com/
Desenvolvimento Web 1 – Jair C Leite
Exercício 1
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(posts => {
console.log('Posts:', posts);
})
.catch(error => {
console.error('Error fetching posts:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Exercício 2
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'My Post',
body: 'This is the content of my post.',
userId: 1,
}),
})
.then(response => response.json())
.then(post => {
console.log('Created Post:', post);
})
.catch(error => {
console.error('Error creating post:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Exercício 3
fetch('https://api.invalidurl.com/data')
.then(response => {
if (!response.ok) {
throw new Error('HTTP error! status: ' + response.status);
}
return response.json();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
console.error('There has been a problem with your fetch
operation:', error);
});
Desenvolvimento Web 1 – Jair C Leite
Referências
W3Schools
Documentação do MDN:
● fetch
● Promises
https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise