Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 是否有必要取消订阅由Http方法创建的观测值?_Angular_Memory Leaks_Rxjs_Angular2 Http - Fatal编程技术网

Angular 是否有必要取消订阅由Http方法创建的观测值?

Angular 是否有必要取消订阅由Http方法创建的观测值?,angular,memory-leaks,rxjs,angular2-http,Angular,Memory Leaks,Rxjs,Angular2 Http,您是否需要取消订阅Angular 2 http调用以防止内存泄漏 fetchFilm(index) { var sub = this._http.get(`http://example.com`) .map(result => result.json()) .map(json => { dispatch(this.receiveFilm(json)); })

您是否需要取消订阅Angular 2 http调用以防止内存泄漏

 fetchFilm(index) {
        var sub = this._http.get(`http://example.com`)
            .map(result => result.json())
            .map(json => {
                dispatch(this.receiveFilm(json));
            })
            .subscribe(e=>sub.unsubscribe());
            ...

调用
unsubscribe
方法是取消正在进行的HTTP请求,因为此方法调用基础XHR对象上的
abort
方法,并删除加载和错误事件的侦听器:

// From the XHRConnection class
return () => {
  _xhr.removeEventListener('load', onLoad);
  _xhr.removeEventListener('error', onError);
  _xhr.abort();
};
也就是说,
unsubscribe
删除侦听器。。。所以这可能是一个好主意,但我不认为一个请求就有必要;-)

希望它能帮助你,
蒂埃里

所以答案是不,你没有<代码>Ng2会自行清理

来自Angular的Http XHR后端源的Http服务源:

注意它在得到结果后如何运行
complete()
。这意味着它实际上在完成时取消订阅。所以你不需要自己做

下面是一个验证的测试:

  fetchFilms() {
    return (dispatch) => {
        dispatch(this.requestFilms());

        let observer = this._http.get(`${BASE_URL}`)
            .map(result => result.json())
            .map(json => {
                dispatch(this.receiveFilms(json.results));
                dispatch(this.receiveNumberOfFilms(json.count));
                console.log("2 isUnsubscribed",observer.isUnsubscribed);
                window.setTimeout(() => {
                  console.log("3 isUnsubscribed",observer.isUnsubscribed);
                },10);
            })
            .subscribe();
        console.log("1 isUnsubscribed",observer.isUnsubscribed);
    };
}
正如预期的那样,您可以看到,在获得结果并使用可观察操作符完成后,它总是自动取消订阅。这发生在一个超时(#3)上,因此我们可以在所有操作完成后检查可观察对象的状态

结果呢

因此,
Ng2
自动退订时不会出现泄漏

值得一提的是:这个
可观察的
被归类为
有限的
,与
无限的
可观察的相反,它是一个无限的数据流,可以像DOM
单击
监听器那样发出


谢谢,@rubyboy在这方面的帮助。

对于新的HttpClient模块,仍然保持相同的行为

您不应该取消订阅自动完成的观察对象(例如Http、调用)。但是有必要取消订阅无限的可观察对象,比如
Observable.timer()

RxJS Observable基本上是关联的,并且在订阅它时相应地工作。当我们创建observable并完成它的移动时,observable会自动关闭并取消订阅

它们以观察者的相同方式工作,但顺序完全不同。 更好的做法是在组件被销毁时取消订阅。我们可以随后通过这样做。$manageSubscription.unsubscribe()

如果我们已经创建了如下所述的可观察语法

** 返回新的可观察对象((观察者)=>{ **//在冷态下可观察到 **观察员:完成() **}) **####你们在说什么

好的,所以有两个理由取消订阅任何可观察到的。似乎没有人在谈论第二个非常重要的原因

  • 清理资源。正如其他人所说,这对于HTTP可观察性来说是一个微不足道的问题。它会自己清理干净的
  • 阻止运行
    subscribe
    处理程序
  • 请注意,使用HTTP observable,当您取消订阅时,它将为您取消浏览器中的基本请求(您将在网络面板中看到红色的“已取消”)。这意味着下载或解析响应不会浪费时间。但这实际上是我下面主要观点的旁白

    数字2的相关性将取决于订阅处理程序的功能:

    如果您的
    subscribe()
    处理程序函数有任何不希望的副作用 如果任何调用都已关闭或释放,则必须取消订阅(或添加条件逻辑)以防止执行

    考虑几个案例:

  • 登录表单。输入用户名和密码,然后单击“登录”。如果服务器运行缓慢,您决定点击Escape关闭对话框,该怎么办?您可能会假设您没有登录,但是如果在您点击escape之后返回http请求,那么您仍然会执行您在那里拥有的任何逻辑。这可能导致重定向到帐户页面,设置不需要的登录cookie或令牌变量。这可能不是您的用户所期望的

  • “发送电子邮件”表格

  • 如果“sendEmail”的
    subscribe
    处理程序执行类似于触发“您的电子邮件已发送”动画的操作,请将您转移到其他页面或尝试访问已处理的任何内容,您可能会遇到异常或不需要的行为

    还要注意不要假定
    unsubscribe()
    表示“取消”。一旦HTTP消息在传输中,如果HTTP请求已经到达您的服务器,则
    unsubscribe()
    将不会取消HTTP请求。它只会取消返回给您的响应。电子邮件可能会被发送出去

    如果您创建订阅以直接在UI组件内发送电子邮件,则可能希望在dispose上取消订阅,但如果电子邮件是由非UI集中服务发送的,则可能不需要取消订阅

  • 被破坏/关闭的角组件。除非您在
    onDestroy()
    中取消订阅,否则此时仍在运行的任何http Observable都将完成并运行其逻辑。结果是否微不足道将取决于您在订阅处理程序中所做的操作。如果你试图更新一些不再存在的东西,你可能会得到一个错误
  • 有时,如果组件被释放,您可能会有一些想要的操作,而有些则不会。例如,对于发送的电子邮件,您可能会听到“swoosh”的声音。即使组件已关闭,您也可能希望播放该动画,但如果尝试在组件上运行动画,则会失败。在这种情况下,subscribe中的一些额外的条件逻辑将是解决方案——并且您不希望取消订阅http observable

    所以在回答实际问题时,不需要这样做来避免内存泄漏。但您需要(经常)这样做,以避免运行可能引发异常或损坏应用程序状态的代码所触发的不必要的副作用

    提示:
    订阅
    包含一个
    已关闭的