Wait for multiple promises to finish

62,190

Solution 1

You can use

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

See also https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Solution 2

You could use Observable.forkJoin from rxjs by providing an array of all the observables/promises. This needs to be done before performing the operation. It's similar to Angular 1's $q.all.

rxjs version <= 6

Observable.forkJoin([
   this.storage.remove(key1), 
   this.storage.remove(key2),
   this.storage.remove(key3)
])
.subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});

rxjs version > 6

import {forkJoin} from 'rxjs';

forkJoin([
   this.storage.remove(key1), 
   this.storage.remove(key2),
   this.storage.remove(key3)
])
.subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});

Solution 3

I'm not familiar with IONIC, but assuming that storage.remove is returning a promise I would suggest you to use forkJoin operator from observables.

forkJoin takes an array of observables and awaits the execution of all items.

Just notice that I had to create 3 new observables from each promise returned by the .remove method.

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]);
});

Solution 4

Use Promise.all():

The Promise.all(iterable) method returns a promise that resolves when all of the promises in the iterable argument have resolved, or rejects with the reason of the first passed promise that rejects.

Syntax

Promise.all(iterable);

Parameters

iterable

An iterable object, such as an Array. See iterable.

Solution 5

use Promise.all for Promisses and Observable.forkJoin for Observables

as the question is about angular(2+) and you problably should have been using Observable instead of promises. i`ll add a GET example that worked for me:

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

note the use one .map() to handle the response rather than .subscribe()

Share:
62,190
Bas van Dijk
Author by

Bas van Dijk

My passion is creating user friendly software, sharing knowledge, thinking out of the box, developing new concepts. Founder of the Drammer whisky app (25K users). In a team I like to get the best out of people, motivate, giving insight, improving skills, sharing knowledge on UI/UX, algorithms and software design patterns. Always been fascinated by computer/network/software security.

Updated on July 24, 2022

Comments

  • Bas van Dijk
    Bas van Dijk almost 2 years

    I am using the SQLStorage from the Ionic platform. The remove function returns a promise. In my code I need to remove multiple values. When these are all finished I need to execute some code.

    How can I wait for all of these and then execute a callback function?

    Code:

    removeAll() {    
      this.storage.remove(key1);
      this.storage.remove(key2);
      this.storage.remove(key3);    
    }
    

    Nesting all is a bad practise so I am looking for a decent solution :)

    removeAll() {
      return this.storage.remove(key1).then(() => {
        this.storage.remove(key2).then(() => {
          this.storage.remove(key3);        
        });
      });
    };
    
  • Manu Valdés
    Manu Valdés almost 8 years
    I would add that if any of these promises rejects, Promise.all will immediately reject (whether or not the rest have finished) and the then will be skipped. If you need to run doSomething() whether they succeed or they fail, you need to catch each of then individually to return a Promise.resolve().
  • My Stack Overfloweth
    My Stack Overfloweth over 7 years
    Observable.forkJoin works for me. Rx.Observable.forkJoin does not.
  • Robouste
    Robouste over 6 years
    With Promise.all(), will they be excecuted one after each other, or all at once ?
  • Günter Zöchbauer
    Günter Zöchbauer over 6 years
    All calls are executed immediately, then Promise.all() just waits for all these promises to complete before it completes itself. This is not a Promise.all feature. With this code Promise.all([ this.storage.remove(key1),, ...]);` this.storage.remove(key1) is called and only the return value (a Promise) is added to the array that is passed to Promise.all(...)