我已经设置了一个RXJS可观察.我有两个组件订阅服务工厂的主题.如何取消订阅所选组件到主题以便按下按钮它会停止收听主题广播?
请参阅我的jsfiddle 取消订阅应用程序
我的代码:
<div ng-app="myApp" ng-controller="mainCtrl">
<script type="text/ng-template" id="/boxa">
BoxA - Message Listener: </br>
<strong>{{boxA.msg}}</strong></br>
<md-button ng-click='boxA.unsubcribe()' class='md-warn'>Unsubscribe A</md-button>
</script>
<script type="text/ng-template" id="/boxb">
BoxB - Message Listener: </br>
<strong>{{boxB.msg}}</strong></br>
<md-button ng-click='boxB.unsubcribe()' class='md-warn'>Unsubscribe B</md-button>
</script>
<md-content class='md-padding'>
<h3>
{{name}}
</h3>
<label>Enter Text To Broadcast</label>
<input ng-model='msg'/></br>
<md-button class='md-primary' ng-click='broadcastFn()'>Broadcast</md-button></br>
<h4>
Components
</h4>
<box-a></box-a></br>
<box-b></box-b>
</md-content>
</div><!--end app-->
var app = angular.module('myApp', ['ngMaterial']);
app.controller('mainCtrl', function($scope,msgService) {
$scope.name = "Observer App Example";
$scope.msg = 'Message';
$scope.broadcastFn = function(){
msgService.broadcast($scope.msg);
}
});
app.component("boxA", …Run Code Online (Sandbox Code Playgroud) 根据我对Angular和RxJ的理解,有两种方法可以终止Observable.你可以unsubscribe()从他们或使用takeUntil()和complete().以下是每种方法的示例(伪代码).
取消订阅()方法
private _id: number;
private _subscriptions: Subscription[] = [];
constructor(private _route: ActivatedRoute) {
this._getId();
}
public ngOnDestroy(): void {
this._subscriptions.forEach(
subscription => subscription.unsubscribe()
);
}
private _getId(): void {
this._subscriptions.push(
this._route.params.subscribe(params => this._id = +params['id'])
);
}
Run Code Online (Sandbox Code Playgroud)
takeUntil()和complete()方法
private _id: number;
private _ngUnsubscribe: Subject<void> = new Subject<void>();
constructor(private _route: ActivatedRoute) {
this._getId();
}
public ngOnDestroy(): void {
this._ngUnsubscribe.next();
this._ngUnsubscribe.complete();
}
private _getId(): void {
this._route.params.takeUntil(this._ngUnsubscribe).subscribe(
params => this._id = +params['id']
);
}
Run Code Online (Sandbox Code Playgroud)
在Angular中,是否有一种终止Observables的首选方法?
我有一个关于 observable 的快速问题。
我有以下可观察的:
getElevation(pos: Cartographic): Observable<Cartographic> {
return new Observable(observer => {
const promise = Cesium.sampleTerrain(this.terrainProvider, 11, Cesium.Cartographic(pos.longitude, pos.latitude))
Cesium.when(promise, (updatedPositions) => {
observer.next(updatedPositions);
observer.complete();
});
});
}
Run Code Online (Sandbox Code Playgroud)
在一个组件中,我有:
this.service.getElevation(value).subscribe((e) => {});
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是一个一次性的observable,所以我完成后,完成后会自动关闭订阅吗?或者,我是否也必须这样做:
const sub = this.service.getElevation(value).subscribe((e) => {sub.unsubscribe();});
Run Code Online (Sandbox Code Playgroud) 我正在探索RxJS库,真的是使用Observable而不是Promise的粉丝.但是,有人可以提供有关使用之间差异的任何详细信息
在这个库中特别需要Single?
我的 Angular 应用程序有很多组件,其中之一是 MyComponent,其组件类如下所示:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
a = 'I still alive';
constructor() {}
ngOnInit() {
Observable.interval(1000).subscribe(x => console.log(this.a));
}
}
Run Code Online (Sandbox Code Playgroud)
如果我访问 MyComponent,订阅将按预期开始。假设我现在离开 MyComponent,并且 MyComponent 现在应该被销毁。但我仍然可以看到订阅仍然存在(控制台日志不断出现)。在主机组件 (MyComponent) 被销毁后允许订阅继续存在有什么实际好处?
(如果我想取消订阅,可以在MyComponent的ngOnDestroy()方法中进行,但如何取消订阅不是这里讨论的重点)
下面的代码工作,它应该监听节点中的更改并执行一个函数,但现在出现错误:
ncaught TypeError: Object(...) is not a function
at SwitchMapSubscriber.eval [as project] (changes.js:7)
Run Code Online (Sandbox Code Playgroud)
所以,在我的angular2组件中,我有:
private subscriptions = new Subscription();
registered: AngularFireList<any>;
constructor(private _af: AngularFireDatabase){
this.registered = _af.list('/registered');
}
ngOnInit() {
this.subscriptions.add(
this.registered.valueChanges().subscribe(
res => {
console.log("the value has changed");
}
)
);
}
Run Code Online (Sandbox Code Playgroud)
所以我在哪里出错,因为得到上面的错误指向:
angular2fire/database/list/changes
Run Code Online (Sandbox Code Playgroud)
我需要我的代码做的是在firebase节点发生更改并登录到控制台时进行监听
订阅也已定义为:
private subscriptions = new Subscription();
Run Code Online (Sandbox Code Playgroud)
将它添加到订阅然后我可以使用onDestroy生命周期并防止内存泄漏,如下所示
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud) 我已经浏览过很多线程,说需要取消订阅FormControl#valueChanges以防止内存泄漏。我了解“何时”和“如何”取消订阅Observables。据我了解,产生无限数量值的 Observables 需要取消订阅,这FormControl#valueChanges就是其中之一Observable。
Observables但我的问题是,为什么这些垃圾没有被收集?我的意思是,当 Angular 组件被破坏时,引用就消失了,对吧?模板中的表单控件不再存在。实例FormControl也消失了。Observable因此,如果、 、的“源”FormControl消失了,那么它的成员为何valueChanges仍然存在并保留其订阅呢?
我一直在寻找一种简单的方法来避免由于未取消订阅而导致的内存泄漏。大多数时候,我只希望后端提供一个响应。然后,我想退订。那么为什么不在回调中调用它呢?
onSubmit(){
var subscription = this.puzzleService.login(this.nameoremail, this.password).subscribe( success =>{
if(success){
this.router.navigate(['/puzzles']);
}
else{
this.message="Login failed. Please try again.";
}
this.loading=false;
subscription.unsubscribe();
});
this.loading=true;
}
Run Code Online (Sandbox Code Playgroud)
请注意将订阅分配给局部变量。然后,将该局部变量锁定在闭包内部,并告知其完成工作时退订。没有类变量,没有takeUntil,仅此而已。
它编译并运行没有错误。我对调试器还不太熟悉,无法确定可观察对象是否实际销毁并随后进行了垃圾回收。
有什么我想念的吗?可以更熟悉调试器的人纠正我吗?因为如果这行得通,我将在所有地方都这样做。除了我的pollWords()函数中...
这似乎比我所提倡的其他解决方案简单得多。我想我甚至根本不需要关闭,因为当我在调试器中查看它时,我看到“ _this”是“ this”的关闭,而“ this”实际上是可观察的。因此,如果有某种方法可以防止“ this”发生麻烦,那么我可以调用“ this.unsubscribe()”并完成操作。并不是说对象引用关闭是一件可怕的事情……
参考文献:
使用带有一个参数的 Pipe 函数与根本不使用 Pipe 相比,有什么区别吗?
我目前正在实施本文中的 takeUntil 取消订阅策略。在这个SO问题的“官方解决方案”中,takeUntil运算符是通过管道发送的。但是,在此页面上使用 takeUntil 时没有使用管道。
因此,我想知道使用带有单个 Rx 运算符的 Pipe 与根本不使用 Pipe 是否有任何区别(内存泄漏/性能等)。
private destroy$ = new Subject();
...
this.potatoService.getPotato()
.pipe(
takeUntil(this.destroy$)
).subscribe(...
Run Code Online (Sandbox Code Playgroud)
相对于
this.potatoService.getPotato()
.takeUntil(this.destroy$)
.subscribe(...
Run Code Online (Sandbox Code Playgroud) 是否需要取消订阅ObservableAngularHttpClient的方法返回?
例如:
this.http.get(url).subscribe(x => this.doSomething());
Run Code Online (Sandbox Code Playgroud)
我需要取消订阅此订阅吗?我问这是因为我不知道 Angular 是否自己处理它。此外,请求是一次性的,而不是连续的。我倾向于认为我不需要。你怎么看?
根据以下帖子: Angular/RxJs 我何时应该取消订阅“订阅”
RxJS 处理一次性订阅,但我在他们的文档中没有找到任何内容。
rxjs ×9
angular ×6
observable ×2
angularfire2 ×1
angularjs ×1
firebase ×1
javascript ×1
memory-leaks ×1
rxjs5 ×1
unsubscribe ×1