Saltar al contenido

¿Cuál es la diferencia entre promesas y observables?

Solución:

Promesa

A Promise maneja un Evento único cuando una operación asincrónica se completa o falla.

Nota: hay Promise bibliotecas que admiten la cancelación, 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 se prefiere sobre Promise porque proporciona las características de Promise y más. Con Observable no importa si desea manejar 0, 1 o varios eventos. Puede utilizar la misma API en cada caso.

Observable también tiene la ventaja sobre Promise ser para interrumpir. Si el resultado de una solicitud HTTP a un servidor o alguna otra operación asincrónica costosa ya no se necesita, el Subscription de un Observable permite cancelar la suscripción, mientras que un Promise eventualmente llamará a la devolución de llamada exitosa o fallida incluso cuando ya no necesite la notificación o el resultado que proporciona.

Mientras que un Promise comienza inmediatamente, un Observable solo comienza si te suscribes. Es por eso que los Observables se llaman perezosos.

Observable proporciona operadores igual que map, forEach, reduce, … similar a una matriz

También hay operadores poderosos como retry(), o replay(), … que a menudo son bastante útiles. Una lista de operadores enviados con rxjs

La ejecución diferida permite construir una cadena de operadores antes de que se ejecute el observable mediante la suscripción, para hacer un tipo de programación más declarativa.

Ambos Promises y Observables proporcionarnos abstracciones que nos ayuden a lidiar con el asincrónico naturaleza 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, revise 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á construyendo un buscando función que debería mostrarle instantáneamente los resultados 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 inundarlo con una tormenta de HTTP peticiones. Básicamente, solo queremos presionarlo una vez que el usuario haya dejado de escribir en lugar de con cada pulsación de tecla.
  • No llegues al punto final de la búsqueda con el mismos parámetros de consulta para solicitudes posteriores.
  • Trate las respuestas fuera de orden. Cuando tenemos varias solicitudes en curso al mismo tiempo, debemos tener en cuenta los casos en los que regresan en un orden inesperado. Imagina que primero escribimos computadora, detente, sale una solicitud, escribimos coche, deténgase, sale una solicitud. Ahora tenemos dos solicitudes en curso. Desafortunadamente, la solicitud que lleva los resultados de computadora vuelve después de la solicitud que incluye los resultados de coche.

La demostración constará simplemente de dos archivos: app.ts y wikipedia-service.ts. Sin embargo, en un escenario del mundo real, lo más probable es que dividiríamos las cosas más.


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 API de Wikipedia con un término de búsqueda determinado. Note que llamamos toPromise con el fin de obtener de un Observable<Response> a un Promise<Response>. Eventualmente terminará 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 es una gran 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 llama search(term.value).

Desenvolvemos el resultado de la Promesa que el método de búsqueda de WikipediaService 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.

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


Dónde Observables realmente brillar

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

Para develar tales superpoderes primero necesitamos obtener un Observable<string> que lleva el término de búsqueda que escribe el usuario. En lugar de enlazar manualmente al evento keyup, podemos aprovechar las ventajas de Angular formControl directiva. Para usar esta directiva, primero necesitamos 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 de nombre en nuestro componente.

Entre bastidores, término expone automáticamente un Observable<string> como propiedad valueChanges al que podemos suscribirnos. 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> que solo emitirá un nuevo valor cuando no haya habido nuevos valores para 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 una pérdida 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 distinctUntilChanged operador justo después de que llamamos debounceTime(400)

Vea el ejemplo de Observable implementación en Plunker

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

En la medida en que estoy usando Http en Angular, estoy de acuerdo en que en los casos de uso normales no hay mucha diferencia al usar 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

  • https://angular-2-training-book.rangle.io/handout/observables/
  • https://angular.io/tutorial/toh-pt6#observables

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

promesa:

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

observable:

  • son cancelables
  • son repetibles por naturaleza, como reintentar y reintentar cuando
  • transmitir datos en varias canalizaciones
  • tener operaciones similares a matrices como mapa, filtro, etc.
  • se puede crear a partir de otras fuentes como eventos
  • son funciones, que se pueden suscribir 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

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *