Angular2 espera a que terminen múltiples promesas


Estoy usando el SQLStorage de la plataforma Ionic. La función remove devuelve una promesa. En mi código necesito eliminar varios valores. Cuando todo esto haya terminado necesito ejecutar algún código.

¿Cómo puedo esperar todos estos y luego ejecutar una función de devolución de llamada?

Código:

removeAll() {

  this.storage.remove(key1);
  this.storage.remove(key2);
  this.storage.remove(key3);

}

Anidar todo es una mala práctica, así que estoy buscando una solución decente:)

removeAll() {

  return this.storage.remove(key1).then(() => {

    this.storage.remove(key2).then(() => {

      this.storage.remove(key3);

    });

  });

};
Author: a darren, 2016-06-15

6 answers

Puede usar

removeAll() {
  Promise.all([
    this.storage.remove(key1),
    this.storage.remove(key2),
    this.storage.remove(key3),
  ]).then(value => doSomething());

Véase también https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

 49
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 17:17:32

Puedes usar Observable.forkJoin desde rxjs proporcionando una matriz de todos los observables/promises. Esto debe hacerse antes de realizar la operación. Es similar a Angular 1 $q.all.

Observable.forkJoin([
   this.storage.remove(key1), 
   this.storage.remove(key2),
   this.storage.remove(key3)
])
.subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});
 22
Author: Pankaj Parkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 15:33:41

No estoy familiarizado con IONIC, pero asumiendo que el almacenamiento.remove está devolviendo una promesa que le sugeriría que use el operador forkJoin de observables.

ForJoin toma una matriz de observables y espera la ejecución de todos los elementos.

Solo tenga en cuenta que tuve que crear 3 nuevos observables de cada promesa de retorno por el .método de eliminación.

Observable.forkJoin([
   Observable.fromPromise(this.storage.remove(key1)), 
   Observable.fromPromise(this.storage.remove(key2)),
   Observable.fromPromise(this.storage.remove(key3))
])
.subscribe(data => {
    console.log(data[0]);
    console.log(data[1]);
    console.log(data[2]);
});
 3
Author: Daniel Pliscki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 17:23:50

Use Promesa.todo por Promesas y Observables.forkJoin para Observables

Ya que la pregunta es acerca de angular(2+) y probablemente deberías haber estado usando Observable en lugar de promesas. agregaré un ejemplo GET que funcionó para mí:

import {Observable} from 'rxjs/Rx';

Observable.forkJoin(
      this._dataService.getOne().map(one => this.one =one),
      this._dataService.getTwo().map(two => this.two two),
      this._dataService.getN().map(n => this.n = n),
     )
    ).subscribe(res => this.doSomethingElse(this.one, this.two, this.n)); 

Tenga en cuenta el uso uno .map() para manejar la respuesta en lugar de .suscribirse()

 2
Author: Sandro Almeida,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-14 08:31:23

Use Promesa.todos():

La Promesa.el método all(iterable) devuelve una promesa que se resuelve cuando todas las promesas en el argumento iterable se han resuelto, o rechaza con la razón de la primera promesa pasada que rechaza.

Sintaxis

Promise.all(iterable);

Parámetros

Iterable

Un objeto iterable, como un Array. Consulte iterable.

 1
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 17:15:05

En rxjs versión > 6 Puedes hacer algo como esto:

import {forkJoin} from 'rxjs';

Y hacer en lugar de Observable.forkJoin esto:

forkJoin([
  this.service1.get(),
  this.service2.get()
]).subscribe(data => {
  this.data1= data[0];
  this.data2 = data[1];
 1
Author: Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 18:16:05