下面的代码是我的嵌套可观察代码。但我想以更聪明的方式改变我的代码。所以我想将此代码更改为不使用嵌套方式。
如何将此代码更改为非嵌套方式?
user: User;
places: Place[];
user_id: string;
this.loginService.getLoginData(email, password).subscribe(
res1 => {
this.user = res1;
this.storageService.saveUserInfo(this.user.userinfo);
this.loginService
.getPlaces(this.user.userinfo.token)
.subscribe(
res2 => {
this.places = res2;
const placeList = this.places.result.place_list.map(place => {
return place.place_cd;
});
const userInfo = new UserInfoImpl(
this.user.userinfo.email,
this.user.userinfo.name,
placeList
);
const account = new AccountImpl(
this.user.userinfo.token,
userInfo
);
this.loginService.postAccount(account).subscribe(
res3 => {
this.user_id = res3;
if (this.user_id) {
this.storageService.saveUserId(this.user_id);
}
},
err => {
console.log('err!!! ', err.message);
}
);
},
err => {
console.log('err!!! ', err.message);
}
);
},
err => {
console.log('err!!! ', err.message);
}
);
答案 0 :(得分:2)
您可能想要使用.concatMap
运算符。虽然.mergeMap
.switchMap
也可以使用。
简化代码:
this.loginService.getLoginData()
.do((data) => this.storeTheData)
.concatMap((logindata) => this.loginService.getPlaces())
.concatMap((placesdata) => this.loginService.postAccount())
.subscribe()
由于你真的做了很多副作用而且你的代码并没有完全被动,所以对此也有不同的方法。您可以收听存储的登录数据更改,以便为您加载其他数据。我将列出一个简单的版本,它可能没有多大意义。
class Store {
loginData = new ReplaySubject<LoginData>(1);
placesData = new ReplaySubject<PlacesData>(1);
}
class AuthService {
constructor(private store: Store, private http: Http) {
}
login() {
this.http.post("login").subscribe(data => this.store.loginData.next(data));
}
}
class PlacesService {
constructor(store: Store, http: Http) {
store.loginData
.switchMap((loginData) => http.get("places" + loginData.placesId))
.subscribe(places => store.places.next(places)
}
}