Asynchronus JavaScript
Neste post será falado sobre o assincronismo do JavaScript.
Sync vs Async
O JavaScript consegue funcionar de duas formas elementarmente: síncrono e assíncrono.
Síncrono
Quando se trata de síncrono, ou seja, sincronismo é de modo claro ter um fluxo de 1 por 1.
Assim sendo, pense que um navegador recebeu a requisição para pegar 3 imagens o JS irá capturar uma resposta dessa request e de modo síncrono só mostrara 1 imagem por vez.
Ao olharmos isso, teremos de modo claro o que é o sincronismo: "Em fila indiana, uma tarefa por vez".
Onde uma tarefa deve ser concluída para que a outra seja iniciada.
Assíncrono
Agora, que se entendeu o que é o "síncronismo" deve se já imaginar do que se trata o "assíncronismo".
Algo que não é síncrono, então, assíncrono é o fluxo em que as tarefas são independentes logo elas funcionam separadamente.
Vamos pegar o exemplo anterior:
- Percebe-se que há diferenças claras no modo de funcionamento como as diferentes filas para cada imagem, ou seja, cada imagemestá sendo carregada de modo independente.
- Sendo assim, o conceito de "1 por 1" não existem nesse fluxo, seria muito mais:
"Cada um no seu pedaço", ou mesmo; "10 tarefas para 10 mãos, cada mão para uma tarefa o que acontecer com uma não interfere na outra e nem impede ela".
Callback
Callbacks são de modo simples uma função dentro de outra função.
Ou seja, pense assim teremos uma primeira função que irá ter uma relação com uma segunda função que será chamada dentro da primeira.
Exemplo:
// Use o `call_nomeFunction`
const steps = (call_stepOne, call_stepTwo) => {
console.log("~ This is steps");
console.log("|> Call step one...");
console.log(call_stepOne());
console.log("|> Call step two...");
console.log(call_stepTwo());
};
const stepOne = () => {
console.log("STEP ONE");
};
const stepTwo = () => {
console.log("STEP TWO")
};
// Ao passar a função não usa-se os parenteses
// ¬ apenas coloque o nome dela
steps(stepOne, stepTwo);
Callback Hell (Inferno de Retorno de Chamada)
Deve se tomar cuidado para não chegar no nível de um Callback Hell, já que isso é uma má pratica. Por vários motivos: código fica mais complexo e dificil de se fazer uma manutenção ou mesmo entender ele.
Veja abaixo o que é exatamente um Callback Hell:
let production = () => {
setTimeout(() => {
console.log("Order received, starting production...");
setTimeout(() => {
console.log("The fruit has been chopped");
setTimeout(() => {
console.log(`${stocks.Liquid[0]} and ${sotcks.Liquids[1]} was added`);
setTimeout(() => {
console.log("The machine was started");
setTimeout(() => {
console.log(`ice dream was placed on ${stocks.Holders[0]}`);
setTimeout(() => {
console.log(`${stocks.Toppings[0]} was added as toppings`);
setTimeout(() => {
console.log("Serve ice scream");
}, 2000);
}, 3000);
}, 2000);
}, 1000);
}, 1000);
}, 2000);
}, 0000);
};
Nesse exemplo percebe-se claramente um alto nível de aninhamento, assim como complexidade para entender o que está de fato acontecendo no código, o que ele faz e tudo isso gera um código ruim (bad code💩).
Que com certeza é exatamente algo que não deseja, para sanar esse problema vieram as promisses (promessas), usando elas a questão do Callback Hell tente a ser "resolvida".
Mas como no JavaScript sempre tem algum remendo a se fazer, posteriormente surgiram o async/await que são temas para mais adiante.
Promisses
Promisses são promessas que são feitas funcionando de forma assíncrona ela espera uma resposta e partir dela seu status vai mudar de "resolve" ou "reject".
Para entende-las melhor vamos entender seu ciclo:
Promisse é feita (prometo a você servir pizza)
|
Pending (estado padrão ao ser criada)
/ \
/ \
/ \
/ \
/ \
Resolve </ \> Reject
(aceitou a promessa) (rejeitou a promessa)
| |
| |
| |
| |
/ \
.then() (então) .catch() (obter erro)
| |
\ /
\ /
\ /
\----> finally <----/
let stocks = {
Fruits: [
"strawberry", "grapes", "banana", "apple"
],
Liquids: [
"water", "ice"
],
Holders: [
"cone", "cup", "stick"
],
Toppings: [
"chocolate", "peanuts"
]
};
let isShopOpen = true;
let order = ( time, work ) => {
return new Promisse(( resolve, reject ) => {
if (isShopOpen) {
setTimeou(() => {
console.log("Our shop is open");
resolve(work());
}, time);
} else {
reject(console.log("Our shop is close."));
}
});
};
order(2000, () => {
console.log(`${stocks.Fruits[1]} was selected`)
})
.then(() => {
return order(0000, () => console.log("Production has started"));
})
.then(() => {
return order(2000, () => console.log("Fruit was chopped"));
})
.catch(() => {
console.log("Custom left");
})
.finnaly(() => {
console.log("Day ended, shop is closed!");
});
Agora veja que o exemplo feito em Callbacks é o mesmo que em Promisses obviamente feitos de forma diferente, porém, preste atenção em como é feita ainda usa-se ele entretanto de uma forma diferente.
E também nota-se muito menos aninhamento de código tornando o código mais "limpo".
Ao criar uma promisse três métodos importantes (em cada um deles vai ser passado um callback):
.then()
-> Será usado quando a promisse estiver com status: resolve.catch()
-> Será usado assim que houver um erro, ou seja, o status for: reject.finnaly()
-> Acontecerá de qualquer forma, obtendo erro ou não
Com esses métodos é feito o tratamento de erros nas Promisses.
Async / Await
Async e Await é vinheram para resolver ajudar a mehorar ainda mais o uso das Promisses.
Com o async a função é determinada como assincrona, ou seja, seu fluxo vai ser "independente".
Para definir quando uma ação deve esperar para ser executada, escutando eventos para ir até a outra ação.
Deve se usar o async assim:
// function
async function sayHello() {
console.log("Say Hello");
}
// arrow function
const sayHello = async () => {
console.log("Say Hello");
};
Ao usar await devemos usar antes da instrução a ter essa espera, deve ter mente que ele só funcionara, se tiver dentro do escopo de uma função assíncrona, ou seja, usar async e await:
const sayHello = async () => {
setTimeout(() => console.log("My name is Mr. Potato"), 2000);
console.log("Say Hello");
};
sayHello();
Algumas referências (estudo/aprofundamento):
- learn-asynchronus-js/ at https://github.com/mrpunkdasilva/learn-asynchronus-js
- https://youtu.be/nRJhc6vXyK4 - Codigo Fonte TV Aprenda Promisses
- https://youtu.be/ZYb_ZU8LNxs - Asynchronous JavaScript Course (Async/Await, Promises, Callbacks)
💡 Nota do autor: E esse foi o artigo, espero que tenha sido em partes esclarecedor.