freeCodeCamp/guide/portuguese/javascript/promises/index.md

175 lines
6.3 KiB
Markdown
Raw Normal View History

---
title: Promises
localeTitle: Promessas
---
## Promessas
JavaScript é single threaded, o que significa que dois bits de script não podem ser executados ao mesmo tempo; eles têm que correr um após o outro. Um Promise é um objeto que representa a conclusão (ou falha) final de uma operação assíncrona e seu valor resultante.
```javascript
var promise = new Promise(function(resolve, reject) {
// do thing, then…
if (/* everything worked */) {
resolve("See, it worked!");
}
else {
reject(Error("It broke"));
}
});
```
## Uma Promessa existe em um desses estados
* Pendente: estado inicial, nem cumprido nem rejeitado.
* Cumprida: operação concluída com sucesso.
* Rejeitado: falha na operação.
O objeto Promise funciona como proxy para um valor não necessariamente conhecido quando a promessa é criada. Ele permite que você associe os manipuladores ao valor de sucesso ou motivo de falha de uma ação assíncrona. Isso permite que os métodos assíncronos retornem valores como métodos síncronos: em vez de retornar imediatamente o valor final, o método assíncrono retorna uma promessa de fornecer o valor em algum momento no futuro.
## Usando 'Then' (Promise Chaining)
Para fazer várias chamadas assíncronas e sincronizá-las uma após a outra, você pode usar o encadeamento de promessas. Isso permite usar um valor da primeira promessa em retornos de chamada posteriores subsequentes.
```javascript
Promise.resolve('some')
.then(function(string) { // <-- This will happen after the above Promise resolves (returning the value 'some')
return new Promise(function(resolve, reject) {
setTimeout(function() {
string += 'thing';
resolve(string);
}, 1);
});
})
.then(function(string) { // <-- This will happen after the above .then's new Promise resolves
console.log(string); // <-- Logs 'something' to the console
});
```
## API Promise
Existem 4 métodos estáticos na classe Promise:
* Promise.resolve
* Promise.reject
* Promise.all
* Promise.race
## Promessas podem ser encadeadas
Ao escrever Promessas para resolver um problema em particular, você pode encadear as mesmas para formar a lógica.
```javascript
var add = function(x, y) {
return new Promise((resolve,reject) => {
var sum = x + y;
if (sum) {
resolve(sum);
}
else {
reject(Error("Could not add the two values!"));
}
});
};
var subtract = function(x, y) {
return new Promise((resolve, reject) => {
var sum = x - y;
if (sum) {
resolve(sum);
}
else {
reject(Error("Could not subtract the two values!"));
}
});
};
// Starting promise chain
add(2,2)
.then((added) => {
// added = 4
return subtract(added, 3);
})
.then((subtracted) => {
// subtracted = 1
return add(subtracted, 5);
})
.then((added) => {
// added = 6
return added * 2;
})
.then((result) => {
// result = 12
console.log("My result is ", result);
})
.catch((err) => {
// If any part of the chain is rejected, print the error message.
console.log(err);
});
```
Isso é útil para seguir um paradigma de _programação funcional_ . Criando funções para manipulação de dados você pode encadear-los juntos para montar um final resultado. Se em algum ponto da cadeia de funções um valor for _rejeitado,_ a cadeia irá pular para o manipulador `catch()` mais próximo.
Para mais informações sobre Programação [Funcional](https://en.wikipedia.org/wiki/Functional_programming) : [Programação Funcional](https://en.wikipedia.org/wiki/Functional_programming)
## Geradores de Função
Em versões recentes, o JavaScript introduziu mais maneiras de lidar com o Promises de maneira nativa. Uma dessas maneiras é o gerador de funções. Geradores de funções são funções "pausáveis". Quando usados com o Promises, os geradores podem tornar o uso muito mais fácil de ler e parecer "síncrono".
```javascript
const myFirstGenerator = function* () {
const one = yield 1;
const two = yield 2;
const three = yield 3;
return 'Finished!';
}
const gen = myFirstGenerator();
```
Aqui está nosso primeiro gerador, que você pode ver pela `function*` syntax. A variável `gen` que declaramos não rodará `myFirstGenerator` , mas sim "este gerador está pronto para uso".
```javascript
console.log(gen.next());
// Returns { value: 1, done: false }
```
Quando `gen.next()` ele irá interromper o gerador e continuar. Como esta é a primeira vez que chamamos `gen.next()` ele executará o `yield 1` e fará `yield 1` pausa até chamarmos `gen.next()` novamente. Quando o `yield 1` é chamado, ele retornará para nós o `value` que foi gerado e se o gerador está ou não `done` .
```javascript
console.log(gen.next());
// Returns { value: 2, done: false }
console.log(gen.next());
// Returns { value: 3, done: false }
console.log(gen.next());
// Returns { value: 'Finished!', done: true }
console.log(gen.next());
// Will throw an error
```
Conforme continuamos chamando `gen.next()` ele continuará indo para o próximo `yield` e pausando a cada vez. Uma vez que não há mais `yield` , ele continuará a executar o restante do gerador, que neste caso simplesmente retorna `'Finished!'` . Se você chamar `gen.next()` novamente, ele lançará um erro quando o gerador terminar.
Agora, imagine se cada `yield` deste exemplo fosse uma `Promise` , o próprio código pareceria extremamente síncrono.
### Promise.all (iterável) é muito útil para vários pedidos para diferentes fontes
O método Promise.all (iterável) retorna um único Promise que resolve quando todas as promessas no argumento iterável foram resolvidas ou quando o argumento iterável não contém promessas. Ele rejeita com a razão da primeira promessa que rejeita.
```javascript
var promise1 = Promise.resolve(catSource);
var promise2 = Promise.resolve(dogSource);
var promise3 = Promise.resolve(cowSource);
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
// expected output: Array ["catData", "dogData", "cowData"]
```
### Mais Informações
Para mais informações sobre promessas: [Promessas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)