我知道这是一个基本的问题,但是来自angular1背景...这让我很烦恼,我无法找到最佳的选择。
所以,这是我的用例:
这是我到目前为止尝试过的:
getUserPreference(){
this._myservice.getUserPrefrence(username).subscribe(response => {
this.rawData = response;
if(!this.rawData.length){
this._myservice.getDefaultPreference().subscribe(response1 => {
this.newUser = true;
this.rawData = response1;
})
this.callFinalFunction(this.rawData);
}
this.callFinalFunction(this.rawData);
})
}
但是上面的代码似乎是新手,必须有一些更好的方法来做到这一点。 任何人都可以在这里帮助我。如果需要更多信息,请告诉我。
答案 0 :(得分:1)
我认为这段代码没有什么问题,或者可以改善它,而不仅仅是在第二次调用中调用final函数的一个小错误。如果第一个api不返回首选项,则最终函数将被调用两次。
getUserPreference(){
this._myservice.getUserPrefrence(username).subscribe(response => {
this.rawData = response;
if(!this.rawData.length){
this._myservice.getDefaultPreference().subscribe(response1 => {
this.newUser = true;
this.rawData = response1;
})
//remove this
this.callFinalFunction(this.rawData);
}
//this will be called twice if second api is already called
this.callFinalFunction(this.rawData);
})
}
或者,您可以尝试使用switchMap或mergeMap运算符。通常,switchMap运算符是用于维护单个内部订阅的mergeMap的更安全默认值。
这使用RxJS 5.5+管道运算符:
import { switchMap } from 'rxjs/operators';
import { of } from 'rxjs';
getUserPreference() {
const userPreference$ = this._myservice.getUserPrefrence(username).pipe(
switchMap(response => {
if(!response.length) {
this.newUser = true;
return this._myservice.getDefaultPreference()
}
return Observable.of(response);
})
);
userPreference$.subscribe(response => {
this.rawData = response;
this.callFinalFunction(this.rawData);
})
}
RxJS <5.5:
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/of';
getUserPreference() {
const userPreference$ = this._myservice.getUserPrefrence(username)
.switchMap(response => {
if(!response.length) {
this.newUser = true;
return this._myservice.getDefaultPreference()
}
return Observable.of(response);
});
userPreference$.subscribe(response => {
this.rawData = response;
this.callFinalFunction(this.rawData);
})
}
答案 1 :(得分:0)
已经有一段时间没有使用旧版本的rxjs了,所以我希望我不会忘记语法。
getUserPreference(){
this._myservice.getUserPrefrence(username).mergeMap(response=>{
if(!response.length){
this.newUser = true;
return this._myservice.getDefaultPreference();
}
return Observable.of(response);
}).subscribe(response=>{
this.rawData = response;
this.callFinalFunction(this.rawData);
})
基本上,您只会订阅一次。如果没有首选项,您将收到defaultPreference响应,否则您将获得用户首选项。
别忘了导入mergeMap和Observable。很抱歉,我不记得旧的导入路径的含义在我目前使用的angular 6中,有一个不同的rxjs版本
答案 2 :(得分:0)
如果您使用的是RxJS 6,则可以处理以下代码
getUserPreference(){
this._myservice.getUserPrefrence(username)
.pipe(
switchMap(response=>{
if(!response){
return this._myservice.getDefaultPreference();
}
return of(response);
}),
map(response=> {
// call the widget function
})
).subscribe(output=>{
// final output
})
答案 3 :(得分:0)
您错过了反应式编程的要点。我在纯RxJS 6中创建了一个示例,以说明一种更好的方法。
class UserService {
private _user: Subject<User> = new ReplaySubject(1);
private _preferences: Subject<UserPreferences> = new ReplaySubject(1);
public get user$(): Observable<User> {
return this._user.asObservable();
}
public get preferences$(): Observable<UserPreferences> {
return this._preferences.asObservable();
}
constructor(private backendService: BackendService) {
this.user$.subscribe(user => {
this.backendService
.getUserPrefrences(user.name)
.pipe(
switchMap(preferences =>
preferences ? of(preferences) :
this.backendService.getDefaultUserPreferneces())
).subscribe(preferences =>
this._preferences.next(preferences)
);
});
}
public login(username: string, password: string): Observable<User> {
let login = this.backendService.login(username, password).pipe(share());
login.subscribe(user => this._user.next(user));
return login;
}
public logout() {
let logout = this.backendService.logout().pipe(share());
logout.subscribe(user => this._user.next(user));
return logout;
}
}
您可以从任何关心它们的组件中订阅user$
和preferences$
的可观察对象,并监听更改。
userService.preferences$.subscribe(preferences => {
console.log('current user preferences : ', preferences);
});