Pregunta Promesa vs Observable


¿Puede alguien explicar la diferencia entre Promise y Observable en Angular?

Un ejemplo de cada uno sería útil para entender ambos casos. ¿En qué situación podemos usar cada caso?


761
2018-05-21 15:43


origen


Respuestas:


Promesa

UN Promise maneja una Evento único cuando una operación asíncrona se completa o falla.

Nota: Hay Promise bibliotecas que admiten cancelaciones, pero ES6 Promise no hasta ahora.

Observable

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

A menudo Observable es preferido sobre Promise porque proporciona las características de Promise y más. Con Observable no importa si quiere manejar 0, 1 o múltiples eventos. Puede utilizar la misma API en cada caso.

Observable también tiene la ventaja sobre Promise ser cancelable. Si ya no es necesario el resultado de una solicitud HTTP a un servidor u otra costosa operación asíncrona, el Subscription de un Observable permite cancelar la suscripción, mientras que Promise eventualmente llamará al éxito o a la devolución de llamada fallida incluso cuando ya no necesite la notificación o el resultado que proporciona.

Observable proporciona operadores me gusta map, forEach, reduce, ... similar a una matriz

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


907
2018-05-21 17:19



Promesas:

  • devolver un valor único
  • no cancelable
  • código más legible con try / catch y async / await

Observables:

  • trabajar con múltiples valores a lo largo del tiempo
  • para interrumpir
  • mapa de soporte, filtro, reducir y operadores similares
  • usar extensiones reactivas (RxJS)
  • una matriz cuyos elementos llegan de forma asincrónica a lo largo del tiempo

239
2018-06-07 12:39



Ambos Promises y Observables bríndenos abstracciones que nos ayuden a manejar el asincrónico naturaleza de nuestras aplicaciones. La diferencia entre ellos fue señalada claramente por @ Günter y @Relu.

Como un fragmento de código vale más que mil palabras, veamos el ejemplo a continuación para comprenderlo mejor.

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


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

Supongamos que está construyendo un buscando función eso debería mostrarle resultados al instante mientras 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, debe inundarlos con una tormenta de HTTP peticiones. Básicamente, solo queremos golpearlo 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 el mismos parámetros de consulta para solicitudes posteriores.
  • Tratar con respuestas fuera de orden. Cuando tenemos varias solicitudes en vuelo al mismo tiempo, debemos dar cuenta de los casos en los que vuelven en orden inesperado. Imagina que primero escribimos computadora, para, se va una solicitud, tecleamos coche, para, se va una solicitud. Ahora tenemos dos solicitudes en vuelo. Desafortunadamente, la solicitud que lleva los resultados para computadora regresa después de la solicitud que lleva los resultados para coche.

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


A continuación es Basado en promesas implementación que no maneja ninguno de los casos extremos 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 Jsonp servicio para hacer un GET solicitud contra el Wikipedia API con un término de búsqueda dado. Observe que llamamos toPromise para llegar desde Observable<Response> a un Promise<Response>. Eventualmente terminan con un 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 hay mucha sorpresa aquí tampoco. Inyectamos nuestro WikipediaService y exponer su funcionalidad a través de un método de búsqueda a la plantilla. La plantilla simplemente se une a tecla Arriba y llamadas search(term.value).

Desplegamos el resultado de la Promesa que el método de búsqueda de WikipediaService lo devuelve y lo expone como una simple matriz de cadenas a la plantilla para que podamos tener *ngFor recorrerlo y crear una lista para nosotros.

Mira el ejemplo de Basado en promesas implementación en Plunker


Dónde Observables realmente brillar

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

Para develar tales superpoderes, primero necesitamos obtener un Observable<string> eso lleva el término de búsqueda que el usuario ingresa. En lugar de vincularlo manualmente al evento keyup, podemos aprovechar Angular's formControl directiva. Para usar esta directiva, primero debemos importar el ReactiveFormsModule en 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 FormControl de @angular/form y exponerlo como un campo bajo el término nombre en nuestro componente.

Entre bastidores, término expone automáticamente una Observable<string> como propiedad valueChanges a que nos podemos suscribir Ahora que tenemos un Observable<string>, superar la entrada del usuario es tan fácil como llamar debounceTime(400) en nuestro Observable. Esto devolverá un nuevo Observable<string> eso solo emitirá un nuevo valor cuando no haya venido nuevos valores por 400ms.

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 cual nuestra aplicación ya muestra los resultados. Todo lo que tenemos que hacer para lograr el comportamiento deseado es llamar al distinctUntilChanged operador justo después de que llamamos debounceTime(400)

Mira el ejemplo de Observable implementación en Plunker

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

Por lo que estoy usando Http en Angular, estoy de acuerdo en que en los casos de uso normal no hay mucha diferencia cuando se usa Observable over 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


199
2017-10-19 15:17



Ambos Promesas y Observables nos ayudará a trabajar con el funcionalidades asincrónicas en JavaScript Son muy similares en muchos casos, sin embargo, todavía hay algunas diferencias entre los dos también, las promesas son valores que se resolverán en asynchronous formas como http llamadas. Por otro lado, los observables tratan con la secuencia de eventos asincrónicos. Las principales diferencias se enumeran a continuación:

promesa:

  • tener una línea de tubería
  • usualmente solo se usa con retorno de datos asíncronos
  • no es fácil de cancelar

observable:

  • son cancelables
  • son reutilizables por naturaleza, como volver a intentar y volver a intentar
  • transmitir datos en múltiples líneas de tubería
  • tener operaciones similares a una matriz, como mapa, filtro, etc.
  • se puede crear a partir de 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:

Promises and Observables image


118
2018-05-07 06:56



Promesas

  1. Definición: lo ayuda a ejecutar funciones de forma asíncrona y usa sus valores de retorno (o excepciones) pero sólo una vez cuando se ejecuta.
  2. No perezoso
  3. No cancelable Las dos posibles decisiones son
    • Rechazar
    • Resolver
  4. No puede ser reintentar(Las promesas deberían tener acceso a la función original que devolvió la promesa para tener una capacidad de reintento, lo cual es una mala práctica)

Observables

  1. Definición: lo ayuda a ejecutar funciones de forma asíncrona y usa sus valores de retorno en una secuencia continua (varias veces) cuando se ejecuta.
  2. Por defecto, es Lazy ya que emite valores cuando el tiempo avanza.
  3. Tiene muchos operadores que simplifican el esfuerzo de codificación.
  4. Un operador rever se puede usar para volver a intentar cuando sea necesario, también si tenemos que volver a intentar el observable en función de algunas condiciones retryWhen puede ser usado.

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


41
2018-01-09 18:29



Hay una desventaja de los Observables que faltan en las respuestas. Las promesas permiten utilizar las funciones ES7 async / await. Con ellos puede escribir código asíncrono 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 tener un valor de retorno nuevamente:

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

Otras lecturas: ¿Cómo puedo 'esperar' en un Rx Observable? 


26
2018-06-28 20:45



Soy un chico de las fotos, esto faltaba en otras respuestas:

enter image description here


15
2017-12-06 19:17



 Promises vs Observables

promesas y Observable ambos están manejando la llamada asincrónica only.find arriba   imagen para la diferencia principal.


13
2018-01-17 16:50