Angular2:使用Observables进行多次同步调用的最佳方法是什么?
在我使用Promises进行服务调用之前,我正在研究Angular2 / 4中的Observables.
我想知道进行多个同步调用的最佳方法是什么. getUserId():Number // return the logged in user userId from the session getUserPermissions(userId):Array<String> // return a list of permission from the userId getUserInfo(userId):String // return some additional info for the user 现在让我假设我有一个User对象如下: export class User { id: number; name: string; info: string; permissions: array<string>; } 我需要使用3个服务调用的结果创建一个User类的新实例,所以我需要运行: > getUserId(); 通过Observable实现这一目标的最佳和最礼貌的方法是什么? 有了承诺,我会有这样的事情: this._service.getUserId().then(r1 => { let userId: number = r1; this._service.getUserPermissions(userId).then(r2 => { let userPermissions: Array<String> = r2; this._service.getUserInfo(userId).then(r3 => { let userInfo: string = r3; let user: User = new User(userId,userInfo,userPermissions); }); }) }); 解决方法
我不能保证这是最好或最礼貌的方式,因为RxJs是一个如此强大的库,你可以用许多不同的方式获得相同的结果,但我会试一试.
我会选择两个选项. 假设您的服务看起来像这样: userservice.ts @Injectable() export class UserService { constructor(private http: Http) { } getUserId(): Observable<{ id: number,name: string }> { return Observable.of({ id: 3,name: 'Bob' }).delay(300); /* * replace with http: * return this.http.get('http://my.api.com/api/user/id').map(res => res.json()); */ } getUserPermission(userId: number): Observable<{ permissions: string[] }> { return Observable.of({ permissions: ['user','admin'] }).delay(300); /* return this.http.get(`http://my.api.com/api/user/${userId}/permissions`).map(res => res.json()); */ } getUserInfo(userId: number): Observable<{ info: string }> { return Observable.of({ info: 'is a nice person'}).delay(300); /* return this.http.get(`http://my.api.com/api/user/${userId}/info`).map(res => res.json()); */ } } 请注意,这些方法返回JSON对象的Observables! switchMap 此方法适用于必须按特定顺序发生的请求. this.userService.getUserId() .switchMap(userResult => this.userService.getUserPermission(userResult.id) .switchMap(permissionsResult => this.userService.getUserInfo(userResult.id) .map(infoResult => ({ id: userResult.id,name: userResult.name,permissions: permissionsResult.permissions,info: infoResult.info })) ) ) .subscribe(v => console.log('switchmap:',v)); 如果打开浏览器的网络选项卡,您将看到请求按顺序执行,这意味着每个请求必须在下一个请求开始之前完成.所以getUserId()必须在getUserPermission()启动之前完成,这反过来必须在getUserInfo()运行之前完成……依此类推. 您也可以使用mergeMap.唯一的区别是,当source observable发出新值时,switchMap可以取消正在进行的http请求.看here进行比较. forkJoin 此方法允许您并行执行请求. this.userService.getUserId() .switchMap(userResult => Observable.forkJoin( [ Observable.of(userResult),this.userService.getUserPermission(userResult.id),this.userService.getUserInfo(userResult.id) ] )) .map(results => ({ id: results[0].id,name: results[0].name,permissions: results[1].permissions,info: results[2].info })) .subscribe(v => console.log('forkJoin:',v)); 由于forkJoin运行并行给出的所有Observable序列,因此如果请求(或至少其中一些请求)不相互依赖,则它是更好的选择. 两种方法都将返回具有以下结构的对象: { "id": 3,"name": "Bob" "permissions": [ "user","admin" ],"info": "is a nice person" } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |