为什么订阅 BehaviorSubject Observable 永远不会触发 onComplete?
Why subscribe on BehaviourSubject asObservable never fires onComplete?
我正在使用 Angular。我有用于存储本地存储数据和从本地存储获取数据的服务。我将 BehaviorSubject 保存为 Observable()。
代码如下:
import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class NavigationStorageService {
ModuleTitle = new BehaviorSubject<string>("");
currentModuleTitle = this.ModuleTitle.asObservable();
constructor() {}
setModuleId(ModuleId) {
localStorage.setItem('subModuleId', ModuleId)
this.ModuleTitle.next(ModuleId);
}
getModuleId() {
this.ModuleTitle.next(localStorage.getItem('subModuleId'));
return this.currentModuleTitle;
}
}
接下来我将使用以下代码获取此数据:
getModuleId() {
this._navigationStorageService.getModuleId()
.subscribe(
subModuleId => {
this.subModuleId = subModuleId
},
error => {
console.log(error)
},
() => console.log("getModuleId"));
}
我的问题是我想在 observable 完成时执行其他函数,但是这个 observable 从未完成所以我不能那样做。
() => console.log("getModuleId") 没有显示消息。
我该如何解决这个问题?
在我的应用程序的另一部分,我使用 Observable 来获取 HttpClient 请求并且它工作正常。我的意思是 onComplete 应该触发。
我试过使用 .finally()
getModuleId() {
this._navigationStorageService.getModuleId()
.finally(() => console.log("getModuleId"))
.subscribe(
subModuleId => {
this.subModuleId = subModuleId
},
error => {
console.log(error)
},
() => console.log("getModuleId"));
}
但没有用。
您使用了错误的 Observable 对象。当您使用 getModuleId() 方法获取 localStorage 的项目时,您会立即获得此值,然后 Observable 就没有意义了。
import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class NavigationStorageService {
ModuleTitle = new BehaviorSubject<string>("");
currentModuleTitle = this.ModuleTitle.asObservable();
constructor() {}
setModuleId(ModuleId) {
localStorage.setItem('subModuleId', ModuleId)
}
getModuleId(id) {
return localStorage.getItem(id);
}
}
仅当您通过调用 complete()
.
告诉他们完成时,主题才会完成
这里的问题是您要实现的目标。可能您永远不希望 Subject 完成,所以您永远不会调用 this.ModuleTitle.complete()
但您仍想将 complete
通知发送到 currentModuleTitle
的 "consumers"。
这意味着您可以使用 take(1)
运算符,它只接受一个值并立即完成链(无需使用 asObservable
)。
currentModuleTitle = this.ModuleTitle.take(1);
现在每次 currentModuleTitle.subscribe()
您都会立即收到一个值并完成。请注意,BehaviorSubject
首先发出其存储的值,因此 currentModuleTitle
的所有消费者实际上只会收到缓存的值,而不会收到进一步的更新。
我正在使用 Angular。我有用于存储本地存储数据和从本地存储获取数据的服务。我将 BehaviorSubject 保存为 Observable()。 代码如下:
import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class NavigationStorageService {
ModuleTitle = new BehaviorSubject<string>("");
currentModuleTitle = this.ModuleTitle.asObservable();
constructor() {}
setModuleId(ModuleId) {
localStorage.setItem('subModuleId', ModuleId)
this.ModuleTitle.next(ModuleId);
}
getModuleId() {
this.ModuleTitle.next(localStorage.getItem('subModuleId'));
return this.currentModuleTitle;
}
}
接下来我将使用以下代码获取此数据:
getModuleId() {
this._navigationStorageService.getModuleId()
.subscribe(
subModuleId => {
this.subModuleId = subModuleId
},
error => {
console.log(error)
},
() => console.log("getModuleId"));
}
我的问题是我想在 observable 完成时执行其他函数,但是这个 observable 从未完成所以我不能那样做。
() => console.log("getModuleId") 没有显示消息。
我该如何解决这个问题?
在我的应用程序的另一部分,我使用 Observable 来获取 HttpClient 请求并且它工作正常。我的意思是 onComplete 应该触发。
我试过使用 .finally()
getModuleId() {
this._navigationStorageService.getModuleId()
.finally(() => console.log("getModuleId"))
.subscribe(
subModuleId => {
this.subModuleId = subModuleId
},
error => {
console.log(error)
},
() => console.log("getModuleId"));
}
但没有用。
您使用了错误的 Observable 对象。当您使用 getModuleId() 方法获取 localStorage 的项目时,您会立即获得此值,然后 Observable 就没有意义了。
import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class NavigationStorageService {
ModuleTitle = new BehaviorSubject<string>("");
currentModuleTitle = this.ModuleTitle.asObservable();
constructor() {}
setModuleId(ModuleId) {
localStorage.setItem('subModuleId', ModuleId)
}
getModuleId(id) {
return localStorage.getItem(id);
}
}
仅当您通过调用 complete()
.
这里的问题是您要实现的目标。可能您永远不希望 Subject 完成,所以您永远不会调用 this.ModuleTitle.complete()
但您仍想将 complete
通知发送到 currentModuleTitle
的 "consumers"。
这意味着您可以使用 take(1)
运算符,它只接受一个值并立即完成链(无需使用 asObservable
)。
currentModuleTitle = this.ModuleTitle.take(1);
现在每次 currentModuleTitle.subscribe()
您都会立即收到一个值并完成。请注意,BehaviorSubject
首先发出其存储的值,因此 currentModuleTitle
的所有消费者实际上只会收到缓存的值,而不会收到进一步的更新。