为什么在共享服务中使用 BehaviorSubject 而不是使用简单的共享变量?

Why to use BehaviorSubject in shared service and not use simple shared variables?

我对在服务中使用 BehiavorSubject 而不是使用共享变量感到有点困惑。如果我创建一个带有共享变量的服务甚至覆盖它们,angular 组件也会检测到这些变化,那么我为什么要使用 BehiavorSubject 而不是共享变量? 例如,在我的项目中,如果用户登录,我会显示一个导航栏,所以我有 ngIf service.isLoggedIn 并且它工作正常。为什么我需要一个服务中的可观察对象并订阅它的事件。如果有人从不同的组件更改此值,它也会在此处更改。我是 angular 的新手,如果我遗漏了什么,请告诉我。 谢谢 (我按照这个例子:https://loiane.com/2017/08/angular-hide-navbar-login-page/

这是一个公平的问题。根据您的评论,将其保留为变量可能是最好和最简单的解决方案。不过,这里有一些我能想到的用例:

  • 每次值改变时执行逻辑。您也可以在变量的 set 函数中执行此操作,但是使用 RxJS 可以让您轻松访问强大的运算符,例如 debounce 和几个映射运算符。每次值更改时都需要调用 API,但您想等到用户完成输入后再点击 API? RxJS 是一个很好的解决方案。

  • 您可以将它与其他可观察值结合使用。也许你有另一个事件流。使该变量成为 Observable,您可以轻松地将对该变量的更改插入到另一个流中。

  • 更好的 Angular 性能。通过使用 BehaviorSubject(这是一种可观察对象),您可以在 Angular 模板中放置对它的引用,并使用 async 管道自动订阅并自动将其标记为更改检测值变化。所以它看起来像这样:service.isLoggedIn | async。如果您以这种方式处理整个组件,您最终可以将 ChangeDetectionStrategy 切换为性能更高的 OnPush。或者更好的是,您可以切换到 ngrxPush 管道并将您的应用程序完全移出 Angular 区域,从而进一步提高性能。

请记住,即使您的更改“神奇地”更新了组件,这种神奇也是有代价的。 Angular 必须弄清楚发生了什么变化,不要认为它一开始就弄清楚了。它会持续监控您的应用程序——每次按钮点击、每次输入,有时甚至悬停事件都会触发更改检测。因此,您可以越多地提供 更改的挂钩,以及 何时 更改,您就可以更轻松地提高性能。

是的,您说得对,可以使用共享变量,反过来可以检测到更改并相应地更新 view

那我们为什么需要Subject or BehaviorSubject

简单的答案是,

如果只是根据更新后的共享变量直接更改视图,

 <div>Result : {{sharedService.result}}</div>

使用共享变量很有意义。因此,在共享服务中,您只需将 result 更改为 10,然后 view 将立即更新为 10 值。

但是

result10 时,在(任何)组件中,您想要 运行 一些 code/logic ???
如何确保当 result 获得 10 值时,某些逻辑将是 运行( 在组件中?

如下所示,

some.component.ts

       if(sharedService.result === 10){  

             // This code can not run with shared variable approach

       }

问:我们可以在组件中写类似上面的东西吗?
答:是的

问:写完后,会不会运行里面写的逻辑?
答:

问:为什么?
A:因为,共享变量是(使用服务的)引用类型。这意味着无论何时您更改该值,应用程序中的所有引用都将更改(对于单例服务),但用 some.component.ts 编写的代码不会 运行 或触发。

问:为什么?
A: 因为在javascript/angular中,要执行这种类型的scenario/code,你应该有一个callback.

的机制

问:什么是回调?
A: 一个可以作为参数传递给任何函数的函数,一旦执行了主函数,它就可以自行执行。

这就是理解BehaviourSubject.

所需要的基础知识

现在,当您在服务中定义一个 behaviourSubject 时,

Shared.Service.ts

    myBehaviorSubject = new BehaviourSubject(); // has ability to register a callback function     

您可以在任何组件中使用 myBehaviorSubject,如下所示,

some.component.ts

    constructor(private sharedService:SharedService){

        // below subscribe line registers a callback function with myBehaviorSubject.

        this.sharedService.myBehavioirSubject.Subscribe((value)=>{     // This is callback function `(value)=>{...}` 

            if(value === 10){   // When value gets 10 value, below code will run automatically

                // This code will run when condition is met

            }
        })
    }

现在,behaviorSubject 有一些额外的机制来发出值。因此,如果我从 this.myBehaviourSubject.next(10) 等任何地方发出 10 值,由于 behaviourSubject 的内部机制,将调用已注册的回调函数。由于它是一个函数,当发出 10 值时,回调函数将自行执行,并将 运行 其他逻辑写入函数内部。

我希望,通过这种理解,您将能够理解为什么 shared variablesbehaviourSubject

不同