Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 promise/observable chain two events?

Tags:

angular

I'm wondering if observable or promise can be used in the following use case in angular 2:

There are two asynchronized upload tasks. I'd like to know how I can detect both tasks are finished.

My upload task (implemented in promise but it's easily be changed to observable if needed) is like this:

myService.upload('upload1').then(() => {
})

myService.upload('upload2').then(() => {
})

How to chain these two events together in either promise or observable so that I know both tasks are finished? Thanks

like image 697
Bagusflyer Avatar asked Feb 15 '16 07:02

Bagusflyer


People also ask

What is difference between Promise and observable in Angular 2?

Promises deal with one asynchronous event at a time, while observables handle a sequence of asynchronous events over a period of time.

Can we use Promise with observable in Angular?

Promises are used in Angular to resolve asynchronous operations, and Observables are used when the data comes from an external source like an API. Promises can be resolved with a single value or an array of values, and Observables emit one or more values over time.

Which is better Promise or observable?

The biggest difference is that Promises won't change their value once they have been fulfilled. They can only emit (reject, resolve) a single value. On the other hand, observables can emit multiple results. The subscriber will be receiving results until the observer is completed or unsubscribed from.


4 Answers

Use forkJoin, which is equivalent to $q.all from Angular 1.x (a and b are observables):

Rx.Observable.forkJoin([a,b]).subscribe(t=> {
        var firstResult = t[0];
        var secondResult = t[1];
});
like image 139
pixelbits Avatar answered Dec 17 '22 23:12

pixelbits


You can use one of the Combining Operators with observables. Observable.zip(), for example, works with promises...

Observable.zip(
    first,
    second,
    function (firstResolvedValue, secondResolvedValue) {
        return firstResolvedValue && secondResolvedValue;
    }
)

zip accepts a variable number of Observables or Promises as parameters, followed by a function that accepts one item emitted by each of those Observables or resolved by those Promises as input and produces a single item to be emitted by the resulting Observable.

like image 29
Sasxa Avatar answered Dec 18 '22 00:12

Sasxa


complete is executed when all the source stream are closed.

Rx.Observable.merge(
  myService.upload('upload1'),
  myService.upload('upload2').subscribe({complete: () => { ... });

if you want to set a max number of results to wait for

Rx.Observable.merge(
  myService.upload('upload1'),
  myService.upload('upload2')
.take(2)
.subscribe({complete: () => { ... });
like image 41
Günter Zöchbauer Avatar answered Dec 17 '22 23:12

Günter Zöchbauer


You can use Promise.all which returns a new Promise that resolves when all of the promises in the argument array have resolved.

Promise.all([myService.upload('upload1'), myService.upload('upload2')]).then(() => {
  // ...
});

Note, if your myService.upload method returned a Promise, rather than Promise, you could access the return values this way:

Promise.all([myService.upload('upload1'), myService.upload('upload2')])
  .then((retValue1, retValue2) => {
  // ...
});
like image 20
Felix Livni Avatar answered Dec 18 '22 00:12

Felix Livni