Reputation: 55
I have the following observables
callOne() {
return new Observable(subscriber => {
subscriber.next(true);
setTimeout(() => {
subscriber.complete();
}, 3000)
})
}
callTwo() {
return new Observable(subscriber => {
subscriber.next(false);
setTimeout(() => {
subscriber.complete();
}, 1000)
})
}
so when i call subscribe to them
this.callOne().subscribe(data => {
console.log(data);
})
this.callTwo().subscribe(data => {
console.log(data);
})
i get immediately true and false printed, even that i setted complete method in the setTimeout.
With that i am saying that in x miliseconds
there can't be emitted new values after the execution of the complete
methhod.
When i try the same but this time the observables are converted into promises
let response1 = await this.callOne().toPromise();
console.log('response1', response1);
let response2 = await this.callTwo().toPromise();
console.log('response2', response2);
then i get printed true from the callOne observable in 3000 miliseconds. Why is that ?
Why when i have promise the complete method is taken into consideration with the setTimeout but with the observable it is not ?
Upvotes: 0
Views: 52
Reputation: 10984
I would imagine the promise does not resolve until the subscriber.complete()
call. Since you used await
, execution will not continue until the promise resolves.
This article actually explains that the promise returned from toPromise()
waits for the observable to complete, then returns the last value: https://levelup.gitconnected.com/rxjs-operator-topromise-waits-for-your-observable-to-complete-e7a002f5dccb
toPromise()
is deprecated though, so I wouldn't bother using it. You can just wrap Observables in Promises instead. Then you can control exactly when they resolve.
callOne() {
const observable = new Observable((subscriber) => {
subscriber.next(true);
setTimeout(() => {
subscriber.complete();
}, 3000);
});
return new Promise((resolve) => {
observable.subscribe((result) => resolve(result));
});
}
This promise will resolve on the first call of subscriber.next()
which I believe is what you were expecting to happen.
Keep in mind Observables can call .next()
repeatedly, but Promises can only resolve once.
Upvotes: 1
Reputation: 7832
Observables and promises are different things even though they might convert one into another.
What you are facing is expected. The promise does not "resolve" until the observable completes, so only after completion it run the logic, and that is how the promises work. Observable in that sense are different.
In fact, if you do not complete the stream, in the subscribe you still getting the code run, but in the promise as the stream never completes, it won't run anything. A very common mistake is to convert into promise from long-life hot observables.
Upvotes: 1
Reputation: 102
you should change something in your code. You have to run next method in setTimout. because when you run next method observables triggered and also you subscribe an observable it will invoke.
callOne() {
return new Observable(subscriber => {
setTimeout(() => {
subscriber.next(true); // you can use like this
subscriber.complete();
}, 6000)
})
}
But when you use await it is working like then() and it will invoke when everything is done like complete.
Upvotes: 2