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)