1

I've an app where I need to execute some deferred code inside an Observable's teardown but can't find a way to wait for this deferred code to be executed.

let observable = new Observable(subscriber => {
    setTimeout(() => subscriber.next('Hello World'), 3000);

    return () => {
        let promise = new Promise(resolve => {
            setTimeout(() => resolve(), 5000);
        });
    };
});

let subscription = observable.subscribe(next => console.log(next));

// So here the teardown callback will be called.
// I want to find a way to wait for the Promise to resolve or reject.
subscription.unsubscribe();

So unsubscribe seems to accept no argument and returns nothing.

Any idea on how to get the promise variable which is inside the Observable's teardown function?

Elie Faës
  • 3,215
  • 1
  • 25
  • 41
  • What about setTimeout(() => {subscriber.next('Hello World'); resolve()}, 5000); ? – siva636 Apr 25 '18 at 16:36
  • Why does the (ub)subscriber need to wait? This question and answer are somewhat related: https://stackoverflow.com/q/43242578/6680611 – cartant Apr 25 '18 at 20:00
  • @siva636 where would you put that? I don’t think the outcome would be the be same wouldn’t it? – Elie Faës Apr 25 '18 at 21:53
  • @cartant ok so I’m not entirely free on what’s going on on the teardown closure, I’m using Ionic native and for the method I want to use, when I call unsubscribe, it automatically (with decorator) call this promise... The thing is, it calls next on the subscriber instance but please, tell me it is not calling it for real. https://github.com/ionic-team/ionic-native/blob/v3.x/src/%40ionic-native/core/plugin.ts. It tearsdown the method by calling a Promise to “cancel it” (I don’t even know if that’s clear ) – Elie Faës Apr 25 '18 at 22:12
  • That looks dodgy AF, to me, but if you read the comments on the answer I linked to, you'll see that it doesn't break any guarantees, IIRC. – cartant Apr 25 '18 at 22:25
  • @cartant what do you mean by “doesn’t break guarantees”? – Elie Faës Apr 26 '18 at 05:31
  • IIRC, there is no guarantee that a source will not call `next` after unsubscription. However, if the code you linked to relies upon the observer's `next` being callable, it's dodgy, as there are definitely RxJS observers where that will not happen. See the comment on the answer linked above. – cartant Apr 26 '18 at 05:37
  • @cartant ok I see your comment, I'm not even sure in which case the next callback would be called... I thought that whenever you unsubscribe from an observable, it closes immediately and nothing except the teardown is being called isn't it? – Elie Faës Apr 26 '18 at 08:44
  • If you look at the implementation of [`next`](https://github.com/ReactiveX/rxjs/blob/6.0.0/src/internal/Subscriber.ts#L208-L217) in the `SafeSubscriber`, you'll see that the setting of its `isStopped` property to `true` upon unsubscription should prevent the wrapped callback from being invoked. However, there is nothing in the [Observable Contract](http://reactivex.io/documentation/contract.html) that says the source cannot continue to call `next` after unsubscription. As for the snippet, it's been a long time since I've messed with Cordova. Maybe I'm wrong, but it looks dodgy, to me. – cartant Apr 26 '18 at 10:47
  • @cartant yes you can call next after subscription but the callback I gave to it will not be called, is that what you are saying? – Elie Faës Apr 26 '18 at 11:25
  • That's what I think will happen, but I could be wrong. – cartant Apr 26 '18 at 12:04
  • @cartant yeah that's what I think too, I've opened an issue for that. So beside this Ionic issue, there's no way to do something with deferred code inside the tear down callback.. – Elie Faës Apr 26 '18 at 12:35
  • You can do deferred stuff - as in the answer linked above - it's just that the unsubscriber cannot wait for anything that's deferred. To the unsubscriber, the `unsubscribe` call is synchronous and nothing is returned from the call. – cartant Apr 26 '18 at 12:42
  • Yep ok thanks for everything – Elie Faës Apr 26 '18 at 16:05

0 Answers0