zone.js / dist / zone-patch-rxjs的用途

时间:2018-06-10 14:36:04

标签: angular rxjs zone.js

可能我对问题太迟了,但无论如何。

有人可以解释我在什么情况下需要导入区域补丁 - zone.js/dist/zone-patch-rxjs。据我所知,补丁已添加到PRthis one的后继者)中。

我在zone项目中使用RxJsAngular,尽管在PR的描述中看到了make rxjs run in correct zone但我还不完全明白它何时可以帮助我或者它应该是什么问题为我解决。

我会很感激像之前/之后的一些代码示例。

提前致谢。

1 个答案:

答案 0 :(得分:8)

您可以在此处查看https://github.com/angular/zone.js/blob/master/NON-STANDARD-APIS.md

我们的想法是让rxjs在不同的情况下进入正确的区域。

zone.js还提供了一个rxjs补丁,以确保rxjs Observable / Subscription / Operator在正确的区域中运行。有关详细信息,请参阅pull请求843.以下示例代码描述了该想法。

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

目前基本上所有rxjs API都包含

  • 可观察
  • 订阅
  • 订户
  • 计划
修补了

,因此每个异步调用都将在正确的区域中运行。

回答你的评论问题。

不,这不正确。 目前,没有补丁,每个回调将在角度区域内部或外部运行取决于发射器。它与创建回调时没有任何关系。

例如。

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

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

在这种情况下,observable是在angular区域之外创建的,但是subscriber.next在angular区域内被调用,所以最后,回调仍然在angular zone中。

使用补丁,回调将在ngzone之外,因为它是在ngzone之外创建的。