Introdução a Promises em JavaScript
Você já sabe que o uso do modelo de assincronia com callbacks facilmente leva à situação de callback hell. Portanto, um novo modelo foi introduzido em JavaScript chamado promises (promise). Vamos estudar este modelo.
Uma promise é um objeto no qual uma função é passada como parâmetro, e dentro dela devemos colocar nosso código assíncrono:
let promise = new Promise(function() {
// código assíncrono
});
Como você vê, eu armazenei o objeto com a promise
na variável promise. Em algum outro
lugar do código, posso aplicar a esta variável
o método then, passando uma função
com o código que deve ser executado
após a conclusão do código assíncrono, escrito
na criação desta promise:
promise.then(function() {
// será executado quando o código assíncrono terminar
});
Parece confuso, então vamos ver um exemplo. Suponha que eu tenha o seguinte código assíncrono:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Suponha que eu queira resolver para ele nossa
tarefa principal da assincronia: executar algum
código após o disparo do temporizador. Ao mesmo tempo,
eu não quero colocar este código dentro do próprio temporizador
e quero que, de alguma forma, o resultado,
escrito por mim na variável result, chegue a este código.
Basicamente, resolvemos esta tarefa nas lições
anteriores através de callbacks e inscrições. Vamos
agora ver como fazer isso com promises.
Primeiro, precisamos envolver nosso código assíncrono em uma promise:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Isso, no entanto, não é suficiente. Devemos indicar explicitamente que nosso código assíncrono foi concluído. Para isso, nos ajudará uma função de resolução especial, que entra automaticamente como o primeiro parâmetro da função, se especificado:
let promise = new Promise(function(resolve) { // indicamos o parâmetro
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Usando a função de resolução, podemos indicar explicitamente à promise que o código assíncrono terminou. Para isso, devemos chamar esta função no local desejado:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // resolvemos a promise
}, 3000);
});
Além disso, se quisermos passar para fora algum resultado do código assíncrono, podemos passá-lo como parâmetro para nossa função de resolução:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // passamos o resultado
}, 3000);
});
Claro, também podemos nos livrar da variável intermediária:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Agora, em qualquer outro lugar, podemos chamar
o método then da nossa promise:
promise.then(function() {
// será acionado quando a promise for resolvida
});
O resultado da promise entrará no primeiro parâmetro da função, se desejarmos especificá-lo:
promise.then(function(result) {
console.log(result); // exibirá o array com o resultado
});
Crie uma promise, dentro da qual haverá um atraso
de 5 segundos, após o qual a promise deve
ser resolvida, retornando como resultado algum
texto. Exiba este texto na tela.