DEV Community

Jorge Rafael
Jorge Rafael

Posted on • Updated on

Javascript - Promise ou Observable

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 ));
Enter fullscreen mode Exit fullscreen mode

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.')
});
Enter fullscreen mode Exit fullscreen mode

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.")

Enter fullscreen mode Exit fullscreen mode

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')

Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)