¿Cuál es la diferencia entre Promesas y Observables?

1399

¿Cuál es la diferencia entre Promisey Observableen Angular?

Un ejemplo de cada uno sería útil para comprender ambos casos. ¿En qué escenario podemos usar cada caso?

Rohit
fuente
23
Te sugiero que leas esta publicación; Angular2 promesa vs observable
erolkaya84
44
en términos más simples angular-2-training-book.rangle.io/handout/observables/...
Pardeep Jain
3
Para cualquiera que lea estas preguntas y respuestas, como alguien que está involucrado en ambos mundos desde un mantenedor, orador y usuario de mucho tiempo, POV, lo aliento a que lea los documentos oficiales de RxJS y la documentación de MDN sobre las promesas. Personalmente, encuentro las respuestas aquí completamente engañosas e incorrectas y creo que son, aunque con buenas intenciones de personas que intentan ayudar, muy dañinas.
Benjamin Gruenbaum
1
Le sugiero que lea este documento oficial angular angular.io/guide/comparing-observables
fgul
Y es por eso que los enlaces se consideran inaceptables como respuestas.
Dave

Respuestas:

1551

Promesa

A Promisemaneja un solo evento cuando una operación asincrónica se completa o falla.

Nota: Existen Promisebibliotecas que admiten la cancelación, pero ES6 Promiseno lo hace hasta ahora.

Observable

Un Observablees como un Stream(en muchos idiomas) y permite pasar cero o más eventos donde se llama la devolución de llamada para cada evento.

A menudo Observablese prefiere sobre Promiseporque proporciona las características de Promisey más. Con Observableeso no importa si desea manejar 0, 1 o múltiples eventos. Puede utilizar la misma API en cada caso.

ObservableTambién tiene la ventaja Promisede ser cancelable . Si el resultado de una solicitud HTTP a un servidor o alguna otra operación asíncrona costosa ya no es necesaria, la Subscriptionopción Observablepermite cancelar la suscripción, mientras Promiseque eventualmente llamará a la devolución exitosa o fallida incluso cuando no necesite la notificación o el resultado que proporciona más.

Observable proporciona operadores como map, forEach, reduce, ... similares a una matriz

También hay operadores poderosos como retry(), o replay(), ... que a menudo son bastante útiles.

Günter Zöchbauer
fuente
180
Entonces, ¿hay una buena razón para usar Promise en lugar de Observable en el caso de devolución de llamada única o también deberían usarse Observables ya que también pueden funcionar de esa manera? Básicamente, ¿es una buena práctica "Observar todas las cosas" o Promesa todavía tiene su lugar?
Josh Werts
75
Si quieres usar el estilo reactivo, solo usa observables en todas partes. Si solo tienes observables, puedes componer fácilmente. Si los mezclas ya no está tan limpio. Si no le importa el estilo reactivo, puede usar promesa para eventos individuales en los que no le importan cancelables y observables las transmisiones de eventos.
Günter Zöchbauer
35
@ GünterZöchbauer Hola, no tengo argumentos en contra de los Observables o la programación funcional. Simplemente estoy afirmando que creo que las personas que se encuentran con Observables principalmente a través de http en NG2 no tienen ninguna razón real para usar Observables sobre Promesas para hacer las llamadas. No pierden nada práctico mediante el uso de promesas. Los operadores antirrebote y reintento son irrelevantes: puede eliminar el rebote con ng-debounce y, si se espera que una llamada falle, generalmente hay un problema con el código. El único momento en que necesitaba trabajar con el reintento de llamadas fue mientras consultaba API inestables de terceros para HVT.
VSO
92
¡Pero no lo olvides Promise, junto con async/ awaithace que tu código vuelva a estar plano! En la mayoría de las situaciones, y en proyectos que no abordan la ciencia de cohetes, no hay necesidad de escribir esas horribles funciones anidadas con cadenas de métodos innecesariamente complicadas. Puede usar async/ awaittoday con transpilers, como TypeScript, y escribir código plano legible por humanos sin ninguna de las rxjsrepeticiones. Probablemente todavía necesitará rxjsalgunas veces en situaciones selectas, porque realmente tiene muchas cosas que ofrecer.
evilkos
15
Esta respuesta es engañosa, un observable no es como una secuencia, es como una función que devuelve una secuencia .
Benjamin Gruenbaum
336

Ambos Promisesy Observablesnos proporcionan abstracciones que nos ayudan a lidiar con la naturaleza asincrónica de nuestras aplicaciones. La diferencia entre ellos fue señalada claramente por @ Günter y @Relu.

Dado que un fragmento de código vale más que mil palabras, pase por el siguiente ejemplo para comprenderlo más fácilmente.

Gracias @ Christoph Burgdorf por el increíble artículo


Angular usa Rx.js Observables en lugar de promesas para tratar con HTTP.

Suponga que está creando una función de búsqueda que debería mostrarle resultados instantáneamente a medida que escribe. Suena familiar, pero hay muchos desafíos que vienen con esa tarea.

  • No queremos llegar al punto final del servidor cada vez que el usuario presiona una tecla, debería inundarlos con una tormenta de HTTPsolicitudes. Básicamente, solo queremos presionarlo una vez que el usuario ha dejado de escribir en lugar de con cada pulsación de tecla.
  • No golpee el punto final de búsqueda con los mismos parámetros de consulta para solicitudes posteriores.
  • Manejar respuestas fuera de orden. Cuando tenemos varias solicitudes en vuelo al mismo tiempo, debemos tener en cuenta los casos en que vuelven en un orden inesperado. Imagine que primero escribimos computadora , paramos, se apaga una solicitud, escribimos auto , paramos, se apaga una solicitud. Ahora tenemos dos solicitudes en vuelo. Desafortunadamente, la solicitud que lleva los resultados para la computadora regresa después de la solicitud que lleva los resultados para el automóvil .

La demostración consistirá simplemente en dos archivos: app.tsy wikipedia-service.ts. Sin embargo, en un escenario del mundo real, probablemente dividiríamos las cosas más arriba.


A continuación se muestra una implementación basada en Promise que no maneja ninguno de los casos límite descritos.

wikipedia-service.ts

import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';

@Injectable()
export class WikipediaService {
  constructor(private jsonp: Jsonp) {}

  search (term: string) {
    var search = new URLSearchParams()
    search.set('action', 'opensearch');
    search.set('search', term);
    search.set('format', 'json');
    return this.jsonp
                .get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
                .toPromise()
                .then((response) => response.json()[1]);
  }
}

Estamos inyectando el Jsonpservicio para realizar una GETsolicitud contra la API de Wikipedia con un término de búsqueda determinado. Tenga en cuenta que llamamos toPromisepara pasar de una Observable<Response>a una Promise<Response>. Finalmente, termina con a Promise<Array<string>>como el tipo de retorno de nuestro método de búsqueda.

app.ts

// check the plnkr for the full list of imports
import {...} from '...';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Wikipedia Search</h2>
      <input #term type="text" (keyup)="search(term.value)">
      <ul>
        <li *ngFor="let item of items">{{item}}</li>
      </ul>
    </div>
  `
})
export class AppComponent {
  items: Array<string>;

  constructor(private wikipediaService: WikipediaService) {}

  search(term) {
    this.wikipediaService.search(term)
                         .then(items => this.items = items);
  }
}

No es una gran sorpresa aquí tampoco. Inyectamos nuestra WikipediaServicey exponemos su funcionalidad a través de un método de búsqueda a la plantilla. La plantilla simplemente se une al keyup y las llamadas search(term.value).

Desenvolvemos el resultado de la Promesa de que el método de búsqueda de WikipediaService regresa y lo exponemos como una simple Matriz de cadenas a la plantilla para que podamos *ngForrecorrerlo y crear una lista para nosotros.

Vea el ejemplo de implementación basada en promesas en Plunker


Donde los observables realmente brillan

Cambiemos nuestro código para no dañar el punto final con cada pulsación de tecla, sino que solo enviaremos una solicitud cuando el usuario dejó de escribir durante 400 ms

Para revelar tales superpoderes, primero debemos obtener un Observable<string>que lleve el término de búsqueda que el usuario ingresa. En lugar de vincular manualmente al evento keyup, podemos aprovechar la formControldirectiva de Angular . Para usar esta directiva, primero necesitamos importarla ReactiveFormsModuleen nuestro módulo de aplicación.

app.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Una vez importado, podemos usar formControl desde nuestra plantilla y configurarlo con el nombre "término".

<input type="text" [formControl]="term"/>

En nuestro componente, creamos una instancia de FormControlfrom @angular/formy la exponemos como un campo bajo el término de nombre en nuestro componente.

Detrás de escena, el término expone automáticamente una Observable<string>propiedad como a la valueChangesque podemos suscribirnos. Ahora que tenemos una Observable<string>, superar la entrada del usuario es tan fácil como llamar debounceTime(400)a nuestro Observable. Esto devolverá un nuevo Observable<string>que solo emitirá un nuevo valor cuando no haya habido nuevos valores durante 400 ms.

export class App {
  items: Array<string>;
  term = new FormControl();
  constructor(private wikipediaService: WikipediaService) {
    this.term.valueChanges
              .debounceTime(400)        // wait for 400ms pause in events
              .distinctUntilChanged()   // ignore if next search term is same as previous
              .subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
  }
}

Sería un desperdicio de recursos enviar otra solicitud de un término de búsqueda para el que nuestra aplicación ya muestra los resultados. Todo lo que tenemos que hacer para lograr el comportamiento deseado es llamar al distinctUntilChangedoperador justo después de que llamamosdebounceTime(400)

Vea el ejemplo de implementación observable en Plunker

Para tratar las respuestas fuera de orden, consulte el artículo completo http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

En cuanto a que estoy usando Http en Angular, estoy de acuerdo en que en los casos de uso normal no hay mucha diferencia cuando uso Observable sobre Promise. Ninguna de las ventajas es realmente relevante aquí en la práctica. Espero poder ver algún caso de uso avanzado en el futuro :)


Aprende más

trungk18
fuente
31
No compro completamente la decisión de convertir el servicio Http en basado en Observable. Cada explicación que escucho se basa en el mismo ejemplo: la búsqueda por término. Pero ese se trata de manejar eventos del navegador. Me gustaría saber cuál es la ventaja de aplicarlo cuando se trata de solicitudes http asíncronas.
Alex Pollan
1
¿Fue accidental la decisión de evitar patrones mixtos?
Alex Pollan
66
@AlexPollan, en realidad hay una buena explicación de los beneficios del servicio http que devuelve un observable en este podcast con Ben Lesh: devchat.tv/js-jabber/… . En última instancia, el principal beneficio es que puede cancelar un observable, y un caso de uso para esto descrito en el enlace anterior, aunque un poco artificial, es que si llama a múltiples API y solo se preocupa por la primera respuesta, sin importar qué de las API que llamó primero le responde, luego puede cancelar las solicitudes a los demás.
nikolasleblanc
2
@nikolasleblanc, ¿estoy seguro de que puedes usar $ q.race () para eso?
jameslouiz
2
@AlexPollan, la ventaja es que un servicio HTTP basado en Observable facilita la cancelación de solicitudes HTTP en pleno vuelo. La condición de carrera en la respuesta de trungk18 se puede resolver simplemente cancelando la suscripción del HTTP observable antes de realizar una solicitud posterior. RXJS switchMap se puede utilizar para solicitudes HTTP activadas por otro observable (por ejemplo, valueChanges). Para observables HTTP independientes, puede darse de baja y volver a suscribirse manualmente.
Stevethemacguy
236

Tanto Promises como Observables nos ayudarán a trabajar con las funcionalidades asincrónicas en JavaScript. Son muy similares en muchos casos, sin embargo, todavía hay algunas diferencias entre los dos, las promesas son valores que se resolverán de asynchronousmanera similar a las llamadas http . Por otro lado, los observables tratan con una secuencia de eventos asincrónicos . Las principales diferencias entre ellos se enumeran a continuación:

promesa:

  • teniendo una tubería
  • por lo general solo se usa con retorno de datos asíncrono
  • no es fácil de cancelar

observable:

  • son cancelables
  • son reevaluables por naturaleza, como reintentar y volver a intentar
  • transmitir datos en múltiples canalizaciones
  • tener operaciones tipo matriz como mapa, filtro, etc.
  • se puede crear desde otras fuentes como eventos
  • son funciones que podrían suscribirse más adelante

Además, he creado la imagen gráfica para ti a continuación para mostrar las diferencias visualmente:

Imagen de promesas y observables

Alireza
fuente
44
promete "no es fácil cancelar", ¿es posible cancelarlos?
Pardeep Jain
10
sí, también hay una forma de cancelarlos ... algunas personas usan bibliotecas de terceros o bluebird ... también usando la biblioteca Q en Angular hay formas de cancelarlo ... pero como dije no es muy útil
Alireza
Tener una tubería a veces tiene ventajas, por ej. en APP_INITIALIZER, si tiene una tubería múltiple, nunca puede terminar a veces o terminar varias veces.
windmaomao
66
cancelar a Promisees la forma incorrecta de pensar en cómo promete. La Promiseresponsabilidad es solo manejar el éxito o el fracaso de una manera compatible asíncrona. Si desea cancelar una solicitud http, cancele la solicitud, no la promesa, y haga que el resultado de la cancelación cumpla o rechace la Promesa. jsfiddle.net/greggman/ea0yhd4p
gman
2
@gman Exactamente. La promesa simplemente representa algún valor futuro . No , no representa la operación que genera el valor . No puede cancelar un valor. No puede volver a intentar un valor. Es solo un valor. Puede o no estar presente todavía, y puede que nunca exista porque ocurrió una excepción, pero eso es todo.
Yona Appletree
75

Promesas

  1. Definición: lo ayuda a ejecutar funciones de forma asincrónica y a usar sus valores de retorno (o excepciones) pero solo una vez cuando se ejecuta.
  2. No perezoso
  3. No cancelable (Existen bibliotecas de Promise que admiten la cancelación, pero ES6 Promise no lo hace hasta ahora). Las dos decisiones posibles son
    • Rechazar
    • Resolver
  4. No se puede volver a intentar (las promesas deben tener acceso a la función original que devolvió la promesa de tener una capacidad de reintento, lo cual es una mala práctica)

Observables

  1. Definición: lo ayuda a ejecutar funciones de forma asincrónica y a utilizar sus valores de retorno en una secuencia continua ( varias veces ) cuando se ejecuta.
  2. Por defecto, es perezoso ya que emite valores cuando pasa el tiempo.
  3. Tiene muchos operadores que simplifica el esfuerzo de codificación.
  4. Un reintento de operador se puede usar para reintentar cuando sea necesario, también si necesitamos volver a intentar el observable en función de algunas condiciones reintentarCuando se puede usar.

    Nota : Una lista de operadores junto con sus diagramas interactivos está disponible aquí en RxMarbles.com

Aravind
fuente
67

Hay una desventaja de los Observables que faltan en las respuestas. Las promesas permiten utilizar las funciones asincrónicas / en espera de ES7. Con ellos, puede escribir código asincrónico como si fuera una llamada de función sincrónica, por lo que ya no necesita devoluciones de llamada. La única posibilidad para que los Observables hagan esto es convertirlos en Promesas. Pero cuando los convierte en Promesas, solo puede volver a tener un valor de retorno:

async function getData(){
    const data = await observable.first().toPromise();
    //do stuff with 'data' (no callback function needed)
}

Lectura adicional: ¿Cómo puedo `esperar 'en un Rx Observable?

Besserwisser
fuente
21
También me sorprendió por qué nadie señaló este beneficio asesino de Promesas: simplicidad y transparencia gracias a async / wait. Me cambié a Promesas solo por la capacidad de escribir código plano. La lógica de negocios simple y el código de interacción de la interfaz de usuario no deberían verse como ciencia espacial y estar contaminados por el infierno anidado de extensiones reactivas. Además, async / await no es solo en el futuro, puede usarlo en aplicaciones de producción pública que ahora usan transpilers. Uso TypeScript 2.3 y es increíble, como un lenguaje real.
evilkos
Genial, pero pensar de una manera reactiva y todo con los RxOperators quizás no sea una característica asesina
JorgeTovar
37

Promises y Observables manejan la llamada asincrónica solamente.

Aquí están las diferencias entre ellos:

Observable

  1. Emite valores múltiples durante un período de tiempo
  2. No se llama hasta que nos suscribamos al Observable
  3. Se puede cancelar mediante el método unsubscribe ()
  4. Proporciona el mapa, para cada uno, filtra, reduce, vuelve a intentar y vuelve a intentar

Promesa

  1. Emite solo un valor a la vez

  2. Llama a los servicios sin .then y .catch

  3. No se puede cancelar

  4. No proporciona ningún operador

nunna del sur
fuente
2
¿Qué quiere decir exactamente con promesa que emite solo un valor único, mientras que observable emite múltiples?
Abel
2
Una promesa no emite ningún valor; una promesa es un valor a lo largo del tiempo. Una promesa multidifunde ese valor para múltiples suscriptores: una vez que cumple la promesa, ya tiene un valor. Un observable es como una función , suscribirse invoca la acción.
Benjamin Gruenbaum
1
@BenjaminGruenbaum Aún no obtuve la media de varios suscriptores, ¿podría proporcionar un enlace o ejemplo? Gracias
Deepak Patidar
2
observable1.subscribe (subscriber1), observable1.subscribe (subscriber2): esto invoca la función varias veces.
Benjamin Gruenbaum
2
Por favor, editar tu post y mostrar el texto real en lugar de las capturas. Otros no pueden copiar y pegar de sus imágenes, y tampoco pueden ayudarlo a corregir los muchos errores gramaticales. Ver aquí para más detalles. Gracias.
Pang
26

Aunque esta respuesta llega tarde, he resumido las diferencias a continuación,

Observable:

  1. Observable es solo un functionque toma an observery devuelve un function Observer: an object with next, error.
  2. El observador permite a subscribe/unsubscribesu flujo de datos, emitir el siguiente valor para el observador, notifyel observador errorse informar al observador sobre elstream completion
  3. Observer proporciona function to handle next valueerrores y final de la secuencia (eventos de interfaz de usuario, respuestas http, datos con sockets web).
  4. Trabaja con multiple valuesel tiempo
  5. Es cancel-able/retry-abley es compatible con operadores como map,filter,reduceetc.
  6. Crear un Observable puede ser - Observable.create()- devuelve Observable que puede invocar métodos en - Observer Observable.from()- convierte una matriz o iterable en - Observable Observable.fromEvent()- convierte un evento en Observable - Observable.fromPromise()- convierte una Promesa en Observable - Observable.range()- devuelve una secuencia de enteros en el rango especificado

Promesa :

  1. Una promesa representa una tarea que terminará en el futuro;

  2. Las promesas se hacen resolved by a value;

  3. Las promesas son rechazadas por excepciones;

  4. No cancellabley vuelvea single value

  5. Una promesa expone una función (then)

    -entonces devuelve un nuevo promise;

    -Permite attachmentque se ejecute en función de state;

    - handlersson guaranteedpara ejecutar en order attached;

Sajeetharan
fuente
20

Acabo de tratar un problema en el que Promesas era la mejor solución, y lo comparto aquí para cualquiera que se encuentre con esta pregunta en caso de que sea útil (esta fue exactamente la respuesta que estaba buscando antes):

En un proyecto Angular2, tengo un servicio que toma algunos parámetros y devuelve una lista de valores para completar los menús desplegables en un formulario. Cuando se inicializa el componente de formulario, necesito llamar al mismo servicio varias veces con diferentes parámetros para definir varios menús desplegables diferentes, sin embargo, si simplemente coloco todas las variables para llamar al servicio, solo el último tiene éxito y el resto error fuera. El servicio que obtiene de la base de datos solo puede manejar una solicitud a la vez.

La única forma de completar con éxito todas las variables del menú desplegable era llamar al servicio de una manera que impidiera que se procesara una nueva solicitud hasta que finalizara la última solicitud, y el mecanismo Promesa / .then resolvió el problema muy bien.

  fetchValueList(listCode): Promise<any> {
      return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
          .map(response => response.json())
          .toPromise();
  }

  initializeDropDowns() {
      this.fetchValueList('First-Val-List')
          .then(data => {
              this.firstValList = data;
              return this.fetchValueList('Second-Val-List')
          }).then(data => {
              this.secondValList = data;
              return this.fetchValueList('Third-Val-List')
          }).then(data => {
              this.thirdValList = data;
          })  }

Definí las funciones en el componente y luego llamé initializeDropDowns () en ngOnInit.

La función fetchValueList devuelve una Promesa, por lo que la primera llamada pasa el primer listCode y cuando la Promesa se resuelve, el valor devuelto está en la variable de datos en el bloque .then donde podemos asignarlo a la variable this.firstValList. Como la función ha devuelto datos, sabemos que el servicio ha finalizado y es seguro volver a llamar con el segundo listCode, el valor de retorno está en la variable de datos en el siguiente bloque .then y lo asignamos a la variable this.secondValList.

Podemos encadenar esto tantas veces como sea necesario para completar todas las variables, y en el último bloque de código simplemente omitimos la declaración de retorno y el bloque termina.

Este es un caso de uso muy específico en el que tenemos un único servicio que debe llamarse varias veces a medida que el componente se inicializa, y donde el servicio tiene que completar su recuperación y devolver un valor antes de que pueda llamarse nuevamente, pero en este caso, El método Promesa / .then fue ideal.

Stephen R. Smith
fuente
3
Esto ciertamente también es posible con observables (de orden superior). Podría, por ejemplo, usarlo scan()para construir una secuencia de observables secuenciales. Sin embargo, su enfoque es quizás más explícito y más fácil de entender.
lex82
1
Puede reemplazar "entonces" con "switchMap" y hacer exactamente lo mismo con observables.
Dr. C. Hilarius
1
El problema con switchMap, según tengo entendido, es que iniciará todas las solicitudes en paralelo y esperará hasta que todas regresen, luego devolverá los valores a la función de llamada, mientras que en mi situación, tengo un solo servidor que no puedo llamé varias veces en paralelo (ya que el servidor descartará las solicitudes inacabadas cuando lleguen nuevas), así que tuve que asegurarme de que cada llamada al servicio de la base de datos se completara antes de comenzar una nueva llamada, y la Promesa / luego parecía ser la mejor y quizás la única forma de resolver eso.
Stephen R. Smith el
1
¿Por qué no usaste mergeMap encadenado? Hasta donde he entendido su código, este es bastante simple y hace el trabajo tan bien como su ejemplo. @ StephenR.Smith
Mineral
1
@Ore ¿Puedes agregar un ejemplo de código para resolver el mismo problema que otra respuesta? Sería una buena referencia y puede ser una buena oportunidad de refactorización en el futuro. El requisito es que cualquier código que no pueda llamar al servicio de backend en paralelo, debe llamar, esperar el valor de retorno y volver a llamar.
Stephen R. Smith
20

Creo que todas las otras respuestas deberían aclarar tus dudas. Sin embargo, solo quería agregar que los observables se basan en la programación funcional, y encuentro muy útiles las funciones que vienen con él como map, flatmap, reduce, zip. La consistencia que logra la web, especialmente cuando depende de las solicitudes de API, es una mejora brutal.

Recomiendo esta documentación , ya que es la documentación oficial de reactiveX y creo que es la más clara que existe.

Si desea entrar en observables, sugeriría esta publicación de 3 partes: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

Aunque está destinado a RxJava, los conceptos son los mismos y está muy bien explicado. En la documentación reactiveX, tiene las equivalencias para cada función. Debes buscar RxJS.

Marc Pérez
fuente
18

Promesa:

  • Proporcionar un único valor futuro;
  • No perezoso;
  • No cancelable;

Observable:

  • Emite múltiples valores a lo largo del tiempo;
  • Perezoso;
  • Para interrumpir;
  • Soporta operadores de mapa, filtro, reducción y similares.

Puede usar promesas en lugar de observables cuando llame a HTTP en Angular si lo desea.

Iosua Sipos
fuente
16

Visión general:

  • Tanto Promises como Observables nos ayudan a lidiar con operaciones asincrónicas. Pueden llamar a ciertas devoluciones de llamada cuando se realizan estas operaciones asincrónicas.
  • Una promesa solo puede manejar un evento, los observables son para flujos de eventos a lo largo del tiempo
  • Las promesas no se pueden cancelar una vez que están pendientes
  • Los datos observables emitidos se pueden transformar utilizando operadores

Siempre puede usar un observable para tratar el comportamiento asincrónico, ya que un observable tiene todas las funciones que ofrece una promesa (+ extra). Sin embargo, a veces esta funcionalidad adicional que ofrece Observables no es necesaria. Entonces sería una sobrecarga adicional importar una biblioteca para que pueda usarlos.

Cuándo usar Promesas:

Use promesas cuando tenga una sola operación asincrónica de la cual desea procesar el resultado. Por ejemplo:

var promise = new Promise((resolve, reject) => {
  // do something once, possibly async
  // code inside the Promise constructor callback is getting executed synchronously

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

//after the promise is resolved or rejected we can call .then or .catch method on it

promise.then((val) => console.log(val))      // logs the resolve argument
       .catch((val) => console.log(val));    // logs the reject argument

Entonces, una promesa ejecuta un código donde se resuelve o rechaza. Si bien la resolución o rechazar que se llama la promesa pasa de un estado pendiente ya sea a un resueltos o rechazada estado. Cuando se resuelve el estado de la promesa then(), se llama al método. Cuando se rechaza el estado de promesa, catch()se llama al método.

Cuándo usar Observables:

Use Observables cuando haya una secuencia (de datos) a lo largo del tiempo que necesite manejar. Una secuencia es una secuencia de elementos de datos que están disponibles a lo largo del tiempo . Ejemplos de transmisiones son:

  1. Eventos de usuario, por ejemplo, eventos de clic o keyup. El usuario genera eventos (datos) con el tiempo.
  2. Websockets, después de que el cliente realiza una conexión WebSocket con el servidor, empuja los datos con el tiempo.

En el Observable en sí se especifica cuándo ocurrió el siguiente evento , cuándo ocurre un error o cuando se completa el Observable . Entonces podemos suscribirnos a este observable, que lo activa y en esta suscripción, podemos pasar 3 devoluciones de llamada (no siempre tiene que pasar todas). Se debe ejecutar una devolución de llamada para el éxito, una devolución de llamada para error y una devolución de llamada para completar. Por ejemplo:

const observable = Rx.Observable.create(observer => {
  // create a single value and complete
  observer.onNext(1);
  observer.onCompleted();
});

source.subscribe(
  x => console.log('onNext: %s', x),   //  success callback
  e => console.log('onError: %s', e),  //  error callback
  () => console.log('onCompleted')     //  completion callback
 );

// first we log: onNext: 1
//  then we log: onCompleted

Al crear un observable, requiere una función de devolución de llamada que proporciona un observador como argumento. En este observador, a continuación, puede llamar onNext, onCompleted, onError. Luego, cuando el Observable esté suscrito, llamará a las devoluciones de llamada correspondientes que se pasaron a la suscripción.

Willem van der Veen
fuente
9

Promesa: proporcione un único valor futuro. No perezoso . No cancelable Rechazará o resolverá.

Observable: proporciona un valor futuro múltiple. Perezoso Cancelable Proporciona otros métodos de mapa en vivo, filtro, reducción.

Gajender Singh
fuente
8

Promesa vs similitud observable primero

  1. Ambos solían manejar código asíncrono.
  2. Por favor, busque ejemplo de promesa. Promise constructor pasa una función de referencia de resolución que se llamará cuando se llame con algún valor al completar alguna tarea asincrónica.

const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve("Hello from a Promise!");
  }, 2000);
});

promise.then(value => console.log(value));

  1. Ejemplo observable ahora. Aquí también pasamos una función a observable, un observador para manejar la tarea asincrónica. A diferencia de la resolución en la promesa, tiene el siguiente método y se suscribe en ese momento.

  2. Entonces ambos manejan tareas asíncronas. Ahora veamos la diferencia.


const observable = new Observable(observer => {
  setTimeout(() => {
    observer.next('Hello from a Observable!');
  }, 2000);
});

observable.subscribe(value => console.log(value));

Promesa vs diferencia observable

Promesa

  1. Resuelve o rechaza un valor único y puede manejar una tarea asíncrona de valor único a la vez.
  2. Una promesa una vez resuelto el valor asíncrono que completa, ya no se puede usar. Solo se usa una vez y aquí se queda corto.
  3. No cancelable
  4. No hay soporte de rxjs para los operadores.

Observable

  1. capacidad de emitir múltiples valores asincrónicos.
  2. Se usa para manejar la secuencia de eventos o valores. Tenga en cuenta que tiene una gran variedad de tareas o valores, y desea que cada vez que se inserte un valor en este se maneje automáticamente. Cada vez que inserta un valor en esta matriz, todos sus suscriptores recibirán el último valor automáticamente.
  3. Los observables son útiles para observar cambios de entrada, intervalos repetidos, valores de difusión a todos los componentes secundarios, notificaciones push de socket web, etc.
  4. Se puede cancelar mediante el método de cancelación de suscripción en cualquier momento.
  5. Otra última buena parte que promete es el soporte para operadores de rxjs. Tiene muchos operadores de tuberías, principalmente mapas, filtros, switchMap, combineLatest, etc. para transformar datos observables antes de suscribirse.

ingrese la descripción de la imagen aquí


ramesh sharma
fuente
6

Tanto Promises como Observables nos ayudan a lidiar con operaciones asincrónicas. Pueden llamar a ciertas devoluciones de llamada cuando se realizan estas operaciones asincrónicas.

Angular usa Observables que es de RxJS en lugar de promesas para tratar con HTTP

Below are some important differences in promises & Observables.

diferencia entre promesas y observables

Srikrushna
fuente
1
Los datos tabulados parecen incorrectos, el título debe intercambiarse
Derrick.X
1
Por favor, editar tu post y mostrar el contenido real como texto en lugar de imágenes. Otros no pueden copiar y pegar de sus imágenes. Ver aquí para más detalles. Gracias.
Pang
6

Una promesa emite un solo evento cuando una actividad asíncrona finaliza o falla.

Un Observable es como un Stream (en muchos idiomas) y permite pasar al menos cero o más eventos donde se requiere la devolución de llamada para cada evento.

Frecuentemente se prefiere Observable sobre Promise ya que brinda los aspectos más destacados de Promise y más. Con Observable no importa si necesita manejar 0, 1 o varios eventos. Puede usar la API similar para cada caso.

Promesa: la promesa emite un valor único

Por ejemplo:

const numberPromise = new Promise((resolve) => {
    resolve(5);
    resolve(10);
});

numberPromise.then(value => console.log(value));
// still prints only 5

Observable: Emite valores múltiples durante un período de tiempo.

Por ejemplo:

  const numberObservable = new Observable((observer) => {
        observer.next(5);
        observer.next(10);
    });

numberObservable.subscribe(value => console.log(value));
// prints 5 and 10

Podemos pensar en un observable como un flujo que emite múltiples valores durante un período de tiempo y se llama a la misma función de devolución de llamada para cada elemento emitido, por lo que con un observable podemos usar la misma API para manejar datos asincrónicos. si esos datos se transmiten como un valor único o como valores múltiples durante un período de tiempo.

Promesa:

  • Una promesa no es perezosa
  • Una promesa no puede ser cancelada

Observable:

  • Observable es perezoso. El "Observable" es lento. No se llama hasta que nos suscribamos.
  • Un Observable puede cancelarse utilizando el método unsubscribe ()
  • Un observable adicional proporciona muchos operadores potentes como mapa, foreach, filtro, reducir, reintentar, reintentar cuando etc.

Promesas angulares vs observables

Dic
fuente
5

Promise emite un único valor, mientras que Observable emite varios valores. Entonces, mientras maneja una solicitud HTTP, Promise puede administrar una sola respuesta para la misma solicitud, pero qué pasa si hay múltiples respuestas a la misma solicitud, entonces tenemos que usar Observable. Sí, Observable puede manejar múltiples respuestas para la misma solicitud.

Promesa

const promise = new Promise((data) =>
{ data(1);
  data(2);
  data(3); })
.then(element => console.log(‘Promise ‘ + element));

Salida

Promise 1

Observable

const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));

Salida

Observable 1
Observable 2
Observable 3
Yogesh Waghmare
fuente
3

A continuación se presentan algunas diferencias importantes en promesas y observables.

Promesa

  • Emite solo un valor único
  • No cancelable
  • No compartible
  • Siempre asíncrono

Observable

  • Emite valores múltiples
  • Se ejecuta solo cuando se llama o alguien se suscribe
  • Puede ser cancelable
  • Se pueden compartir y suscribir ese valor compartido por varios suscriptores. Y todos los suscriptores se ejecutarán en un solo punto de tiempo.
  • posiblemente asincrónico

Para una mejor comprensión, consulte https://stackblitz.com/edit/observable-vs-promises

Bikram
fuente
3

Veo a muchas personas usando el argumento de que Observable es "cancelable", pero es bastante trivial hacer que Promise sea "cancelable"

function cancellablePromise(body) {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res; reject = rej;
    body(resolve, reject)
  })
  promise.resolve = resolve;
  promise.reject = reject;
  return promise
}

// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('10', 100))
})

p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console

// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
  setTimeout(() => resolve('blop'), 100)
})

p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200

Batiste Bieler
fuente
2

Respuesta corta :

Observable es mejor , tiene todas las características de Promises más características adicionales.


Respuesta larga:

Promesas:

  • Uso único "Devolver datos una vez"
  • No cancelar
  • Un oyente
  • No Socket Support One Listener

Observable:

  • Devolver datos muchas veces a medida que cambian los datos
  • Soporte cancelar
  • Socket de soporte
  • Admite muchos oyentes y notifícalos cuando cambien los datos
  • Mapa de soporte, filtro, reducir
Amr Ibrahim
fuente
No creo que puedas decir que los observables son objetivamente mejores. Hay varias desventajas de los Observables que se observan en las diferentes respuestas aquí. Los que se destacan para mí son la complejidad de Observable y que no funcionan directamente con wait / async. Personalmente, considero que es muy difícil trabajar con ellos porque no se puede determinar el comportamiento de un Observable cuando se usa; debe mirar el código que lo generó. Mientras que con una promesa, siempre sabes exactamente cómo funcionan. Por ejemplo, a veces suscribirse a un Observable tiene efectos secundarios (por ejemplo, una solicitud http), pero a veces no.
Yona Appletree
Para angular, depende de su caso. En la mayoría de los casos, trabajaremos con servicios y algunos datos que afectarán diferentes lugares, sockets, cancelaciones, mapas, filtros y reducciones. Por lo tanto, será mejor en esos casos, ya que las promesas no los respaldan. lo que de nuevo depende de su caso
Amr Ibrahim
2

Si bien la respuesta aceptada es buena en general, no creo que haga hincapié en que cuando se trata de componentes angulares casi siempre desea usar un observable porque admite la cancelación. Las promesas no se pueden cancelar y se resolverán incluso si se destruye su componente. Angular tiende a ser indulgente hasta que no lo es.

Por ejemplo, cualquier detección de cambio manual en un componente destruido causará una excepción:

ngOnInit() {
  // promise api
  this.service.getData().then(d => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });

  // observable api
  this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
     this.data = d;
     this.changeDetectorRef.detectChanges();
  });
}

Si su componente se destruye antes de que se resuelva la promesa, recibirá un attempt to use destroyed viewerror cuando se resuelva la promesa.

Alternativamente, si utiliza observables con el patrón takeUntil , tan pronto como se destruya su componente, se cancelará la suscripción.

Este es un ejemplo un poco artificial, pero la ejecución de código para un componente que se destruye probablemente conducirá a errores. A menos que realmente quiera hacer eso por alguna razón: p

shusson
fuente
2

Algo con lo que me encontré que no era evidente en una primera lectura del tutorial y los documentos fue la idea de multidifusión.

Asegúrese de saber que, de forma predeterminada, las suscripciones múltiples desencadenarán múltiples ejecuciones en un Observable. Múltiples suscripciones a una sola llamada HTTP Observable activará múltiples llamadas HTTP idénticas a menos que usted .share()(habilite la multidifusión).

Una promesa lo obliga a lidiar con una cosa a la vez, desenvolver sus datos, manejar excepciones, tiene soporte de idioma para cosas interesantes como async / wait y, de lo contrario, es bastante básico.

Un Observable tiene muchas campanas y silbatos, pero necesita comprender el poder con el que está trabajando o puede ser mal utilizado.

rpgFANATIC
fuente
2

Promesa:

Un controlador de eventos asíncrono: el objeto Promise representa la finalización (o falla) eventual de una operación asincrónica y su valor resultante.

Sintaxis: nueva promesa (ejecutor);

P.ej:

var promise_eg = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

promise_eg.then(function(value) {
  console.log(value);
  // expected output: "foo"
});

console.log(promise_eg);

ingrese la descripción de la imagen aquí

Acerca de Promise: tiene una canalización, por lo que devolverá valores solo una vez cuando se llame. es un controlador unidireccional, por lo que una vez llamado, es posible que no pueda cancelar. sintaxis útil con la que puedes jugar, cuando () y luego ()

Observables:

Los observables son colecciones perezosas de múltiples valores a lo largo del tiempo. Es realmente un gran enfoque para las operaciones asíncronas. se puede hacer con rxjs que tiene soporte multiplataforma que se puede usar con angular / reaccionar, etc.

actúa como un transatlántico. puede ser de múltiples tuberías. así que una vez definido, puede suscribirse para obtener resultados de retorno en muchos lugares.

Sintaxis: import * as Rx from "@reactivex/rxjs"; para iniciar:

Rx.Observable.fromEvent(button, "click"),
Rx.Subject()

etc.

Suscribirse: RxLogger.getInstance();

P.ej:

import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';

range(1, 200).pipe(
  filter(x => x % 2 === 1),
  map(x => x + x)
).subscribe(x => console.log(x));

Dado que admite múltiples canalizaciones, puede suscribirse a resultados en una ubicación diferente, ingrese la descripción de la imagen aquí tiene muchas posibilidades que las promesas.

Uso: tiene más posibilidades comomap, filter, pipe, map, concatMap etc

Mohideen bin Mohammed
fuente
2

La diferencia básica entre observables y promesas son:

ingrese la descripción de la imagen aquí

Chirag
fuente
2
Por favor, editar tu post y mostrar el contenido real como texto en lugar de imágenes. Otros no pueden copiar y pegar de sus imágenes. Ver aquí para más detalles. Gracias.
Pang
1

Los observables a menudo se comparan con las promesas. Aquí hay algunas diferencias clave:

Los observables son declarativos; El cálculo no comienza hasta la suscripción. Las promesas se ejecutan inmediatamente en la creación. Esto hace que los observables sean útiles para definir recetas que se pueden ejecutar siempre que necesite el resultado.

Los observables proporcionan muchos valores. Las promesas proporcionan una. Esto hace que los observables sean útiles para obtener múltiples valores a lo largo del tiempo.

Los observables diferencian entre encadenamiento y suscripción. Las promesas solo tienen cláusulas .then (). Esto hace que los observables sean útiles para crear recetas de transformación complejas para ser utilizadas por otras partes del sistema, sin que el trabajo se ejecute.

Observables subscribe () es responsable de manejar los errores. Las promesas empujan los errores a las promesas del niño. Esto hace que los observables sean útiles para el manejo centralizado y predecible de errores.

Esa es la diferencia más simple que puede encontrar en los documentos ANGULAR.IO. la respuesta de descanso es dada por la mayoría es correcta en su propio lugar

ankita kumari
fuente
1
  1. Las promesas se centran solo en valores individuales o resuelve, los observables son un flujo de datos.

  2. Los observables pueden cancelarse pero las promesas no pueden cancelarse.

El menos conocido, al menos para mí es

  1. Las promesas son siempre de naturaleza asincrónica, pero los observables pueden ser tanto sincrónicos como asincrónicos.
Vignesh
fuente
0
  1. una promesa está ansiosa, mientras que un observable es perezoso,
  2. una Promesa siempre es asíncrona, mientras que un Observable puede ser síncrono o asíncrono,
  3. una Promesa puede proporcionar un valor único, mientras que un Observable es un
    flujo de valores (de 0 a múltiples valores),
  4. puede aplicar operadores RxJS a un Observable para obtener una nueva secuencia personalizada.
Yogesh Waghmare
fuente
-1

Observables and Promises nos están ayudando a trabajar con las funcionalidades asincrónicas en JavaScript / mecanografiado. Son muy similares en muchos casos, sin embargo, todavía hay algunas diferencias entre ellos.

ingrese la descripción de la imagen aquí

FAISAL
fuente
1
Por favor, editar tu post y mostrar el texto real en lugar de las capturas. Otros no pueden copiar y pegar de sus imágenes. Ver aquí para más detalles. Gracias.
Pang
Excepto que no es código sino información simple, así que creo que está bien publicarlo como una imagen
Alator
1
deja de copiar y pegar de los videos de Kudvenkat en youtube. ¡Vota por mí! :)
Pratik
-2

Ya hay muchas respuestas sobre este tema, así que no agregaría una redundante.

Pero para alguien que acaba de comenzar a aprender Observable / Angular y se pregunta cuál usar en comparación con Promise , le recomendaría que mantenga todo Observable y convierta todas las Promesas existentes en su proyecto en Observable.

Simplemente porque el marco angular en sí y su comunidad están utilizando Observable. Por lo tanto, sería beneficioso integrar servicios de marco o módulos de terceros y encadenar todo.


Si bien aprecio todos los votos negativos, pero insisto en mi opinión anterior, a menos que alguien haga un comentario adecuado para enumerar algunos escenarios que aún podrían ser útiles en su proyecto Angular para usar Promesas sobre Observables.

Por supuesto, ninguna opinión es 100% correcta en todos los casos, pero al menos creo que el 98% del tiempo para proyectos comerciales regulares implementados en un marco angular, Observable es el camino correcto.

Incluso si no te gusta en el punto de partida de tu simple proyecto de pasatiempo, pronto te darás cuenta de que casi todos los componentes con los que interactúas en Angular, y la mayoría del marco de terceros amigable de Angular está usando Observables, y luego podrás terminó convirtiendo constantemente su Promesa en Observable para comunicarse con ellos.

Esos componentes incluyen, entre otros: HttpClient, Form Builder, Módulos / cuadros de diálogo de material angular, Ngrx store / effects y ngx-bootstrap.

De hecho, la única promesa del ecosistema angular con la que traté en los últimos 2 años es APP_INITIALIZER.

Xinan
fuente