Existem dois termos que são aplicados quando falamos desses conceitos; Eles são, Eager e Lazy ( ansioso e preguiçoso ) e a principal diferença entre os dois, são respectivamente as definições desse termos.
Como assim? Vou explicar logo abaixo.
Eager & Lazy
Vamos começar com o seguinte exemplo de Promise
const greetingEager = new Promise((resolve, reject) => {
console.log('Dentro da promise as coisas acontecem de forma anciosa.');
resolve('Olá, Prazer em te conhece.');
})
greetingEager.then( res => console.log('Saudação na Promisse: ' + res ));
No exemplo acima conseguimos ver como ela é ansiosa, porque ao declarar a Promise o conteudo dela já é executado imediatamente, sem mesmo esperar ser invocada através do then
.
Se você executar esse código acima verá que a mensagem do console.log
dentro da Promise é executada antes mesmo de você chamar o then
da função.
Ao contrário de um Observer, que por essência é preguiçoso.
//https://rxjs-dev.firebaseapp.com/guide/overview
const { Observable } = rxjs;
const greetingLazy = new Observable(observer => {
console.log('Dentro de um observer as coisas acontecem de forma preguiçosa.');
observer.next('Olá, fique a vontade.');
observer.complete();
});
console.log('Antes de começar inscreva-se no Observer');
greetingLazy.subscribe({
next: console.log,
complete: () => console.log('Fim da conversa.')
});
Quando você cria um Observable, você precisa fornecer uma função de retorno de chamada através do atributo next, que será invocada sempre que for executado o next dentro do observer.
Para entender um pouco mais sobre isso, tem um post sobre Generator que pode te ajudar.
No exemplo acima a mensagem "Antes de começar inscreva-se no Observer" vai aparecer antes do console.log de dentro do Observable.
Um exemplo seria um cenário onde você quer obter uma informação sobre o cardápio de um restaurante. A promise, seria um menu na sua mesa. onde ao chegar o menu já está disponível para você. Enquanto o Observable, o menu só irá vir até você quando você pedir para um garçom trazer.
Sync & Async
Uma outra diferença é o tipo de execução um observable pode ser síncrono ou assíncrono dependendo do contexto, enquanto a Promise sempre vai ser assíncrona, mesmo que seja resolvida imediatamente após sua execução.
const greeting = new Promise((resolve, reject) => {
resolve('Olá, prazer em te conhecer.')
})
console.log('Antes de chamar a Promise')
greeting.then(res => console.log('Saudação da Promisse: ' + res ));
console.log("Depois de chamar o then na Promise provando que ela inicia sempre de maneira assíncrona.")
No exemplo acima, apesar da execução dessa promise ser imediata, você vai perceber ao rodar o código, que a mensagem de dentro da Promise aparecerá por ultimo. Isso porque uma vez que é declarada a Promise a chamada dela é adicionada a fila de microtasks, ela será só executada no fim da microtask atual.
const { Observable } = rxjs;
const greeting = new Observable(observer => {
observer.next('Olá, Estou muito feliz em ver você');
observer.complete();
});
console.log('Antes de chamar o subscribe do Observable');
greeting.subscribe({
next: console.log,
complete: () => console.log('Fim da saudação')
});
console.log('Depois de chamar o subscribe do Observable, provando que ele pode ser executado de forma síncrona')
No exemplo a cima, a ordem das mensagem serão mantidas. por seguir uma ordem de processos de execução de tasks.
Porém, podemos executar coisas dentro do Observable de forma assíncrona também, como no código a seguir.
const tiredGreeting = new Observable(observer => {
setTimeout(() => {
observer.next('Ah, hey, prazer em te conhecer');
observer.complete();
}, 2000);
});
console.log('Antes de chamar o subscribe do Observable');
tiredGreeting.subscribe({
next: console.log,
complete: () => console.log('Fim da saudação')
});
console.log('Depois de chamar o subscribe do Observable, provando que ele pode ser executado de forma assíncrona')
Valores
Um Observable pode emitir vários valores/resultados para enquanto estiver inscrito.
Enquanto a Promise retorna apenas um resultado, independente de quantas vezes você chame aquela mesma promise.
const { Observable } = rxjs;
const notifications$ = new Observable(observer => {
const interval = setInterval(() => {
observer.next('Nova Noticia.');
}, 2000);
return () => clearInterval(interval);
});
const subscription = notifications$.subscribe(console.log);
setTimeout(() => subscription.unsubscribe(), 8000);
No exemplo de cima, enquanto não há uma desinscrição do Observable, ele ficará emitindo valores.
Como no exemplo do restaurante. A Promise é o menu, ele sempre estará lá, da mesma forma. Enquanto no observable, toda vez que chega alguém novo, o Garçom pode chegar com o Menu, ou com outra informação ao cliente que ele achar relevante.
Recapitulando.
- Promise são ansiosas, enquanto Observable são preguiçosos.
- Promise sempre são assíncronas, enquanto Observable pode ser tanto síncronas quanto assíncronas.
- Promise sempre retornam o mesmo valor, enquanto Observable pode retornar um fluxo de valores, de nenhum a vários.
Nota de rodapé
O Observable, pode ser aprimorado usando outras ferramentas dentro do RxJS, para tornar ele ainda mais poderoso, conseguindo definir fluxos sobre medida.
Nota de tradução
Esse texto é uma adaptação do texto original JavaScript Theory: Promise vs Observable em Inglês no Medium.
Top comments (0)