Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of zone.js/dist/zone-patch-rxjs

Probably I am too late with the question but anyway.

Could someone explain me in what cases I need to import zone's patch - zone.js/dist/zone-patch-rxjs. As far as I know the patch was added in this PR (successor of this one).

I use zone and RxJs in my Angular project and despite seeing make rxjs run in correct zone in PR's description I do not fully understand when it can help me or what problems it should resolve for me.

I would appreciate some code examples like before/after.

Thanks in advance.

like image 368
Sergey Sokolov Avatar asked Jun 10 '18 14:06

Sergey Sokolov


1 Answers

You can check it here, https://github.com/angular/angular/blob/master/packages/zone.js/NON-STANDARD-APIS.md

The idea is to let rxjs run into correct zone in different cases.

zone.js also provide a rxjs patch to make sure rxjs Observable/Subscription/Operator run in correct zone. For details please refer to pull request 843. The following sample code describes the idea.

const constructorZone = Zone.current.fork({name: 'constructor'});
const subscriptionZone = Zone.current.fork({name: 'subscription'});
const operatorZone = Zone.current.fork({name: 'operator'});

let observable;
let subscriber;
constructorZone.run(() => {
  observable = new Observable((_subscriber) => {
    subscriber = _subscriber;
    console.log('current zone when construct observable:', 
      Zone.current.name); // will output constructor.
    return () => {
      console.log('current zone when unsubscribe observable:', 
      Zone.current.name); // will output constructor.
    }
  });
}); 

subscriptionZone.run(() => {
  observable.subscribe(() => {
    console.log('current zone when subscription next', 
      Zone.current.name); // will output subscription. 
  }, () => {
    console.log('current zone when subscription error', d 
      Zone.current.name); // will output subscription. 
  }, () => {
    console.log('current zone when subscription complete', 
      Zone.current.name); // will output subscription. 
  });
});

operatorZone.run(() => {
  observable.map(() => {
    console.log('current zone when map operator', Zone.current.name); 
    // will output operator. 
  });
});

Currently basically everything the rxjs API includes

  • Observable
  • Subscription
  • Subscriber
  • Operators
  • Scheduler

is patched, so each asynchronous call will run in the correct zone.

To answer your comment question.

No, it is not correct. Currently, without the patch, every callback will run inside or outside of angular zone depends on the emitter. It will have nothing to do with when the callback was created.

for example.

let sub;
ngZone.runOutsideAngular(() => {
   const observable = new Observable(subscriber => sub = subscriber));
   observable.subscribe(() => {
      // in ngzone
   });
});

ngZone.run(() => {
  sub.next(1);
});

in this case, the observable was created outside of angular zone, but the subscriber.next was called inside angular zone, so finally, the callback will still in angular zone.

with the patch, the callback will be out side of ngzone because it is created outside of ngzone.

like image 54
jiali passion Avatar answered Nov 03 '22 00:11

jiali passion