在愉快地与AngularJS 1合作之后,我目前正在try 自学Angular2和打字脚本.*在过go 的四年里!我不得不承认我讨厌它,但我相信我的尤里卡时刻就在眼前...无论如何,我已经在我的虚拟应用程序中编写了一个服务,该服务将从我编写的提供JSON服务的假后端获取http数据.

import {Injectable} from 'angular2/core';
import {Http, Headers, Response} from 'angular2/http';
import {Observable} from 'rxjs';

@Injectable()
export class UserData {

    constructor(public http: Http) {
    }

    getUserStatus(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserInfo(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/profile/info', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserPhotos(myId): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    private handleError(error: Response) {
        // just logging to the console for now...
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }   
}

现在在一个组件中,我希望同时运行(或链接)getUserInfo()getUserPhotos(myId)个方法.在AngularJS中,这很容易,因为在我的控制器中,我会这样做以避免"末日 pyramid "...

// Good old AngularJS 1.*
UserData.getUserInfo().then(function(resp) {
    return UserData.getUserPhotos(resp.UserId);
}).then(function (resp) {
    // do more stuff...
}); 

现在我试着在我的组件中做一些类似的事情(用.subscribe替换.then),但是我的错误控制台快疯了!

@Component({
    selector: 'profile',
    template: require('app/components/profile/profile.html'),
    providers: [],
    directives: [],
    pipes: []
})
export class Profile implements OnInit {

    userPhotos: any;
    userInfo: any;

    // UserData is my service
    constructor(private userData: UserData) {
    }

    ngOnInit() {

        // I need to pass my own ID here...
        this.userData.getUserPhotos('123456') // ToDo: Get this from parent or UserData Service
            .subscribe(
            (data) => {
                this.userPhotos = data;
            }
        ).getUserInfo().subscribe(
            (data) => {
                this.userInfo = data;
            });
    }

}

我显然做错了什么...如何最好地使用Observable和RXJ?抱歉,如果我问了一些愚蠢的问题...但是提前谢谢你的帮助!我还注意到,在声明http头时,函数中重复了代码...

推荐答案

对于您的用例,我认为flatMap运算符是您所需要的:

this.userData.getUserPhotos('123456').flatMap(data => {
  this.userPhotos = data;
  return this.userData.getUserInfo();
}).subscribe(data => {
  this.userInfo = data;
});

这样,在收到第一个请求后,您将执行第二个请求.当您想要使用上一个请求(上一个事件)的结果来执行另一个请求时,flatMap运算符特别有用.不要忘记导入操作员以便能够使用它:

import 'rxjs/add/operator/flatMap';

这个答案可以提供更多细节:

如果你只想使用subscribe法,你可以使用这样的方法:

this.userData.getUserPhotos('123456')
    .subscribe(
      (data) => {
        this.userPhotos = data;

        this.userData.getUserInfo().subscribe(
          (data) => {
            this.userInfo = data;
          });
      });

若要完成,如果您希望并行执行两个请求,并且在所有结果都被通知时,应考虑使用Observable.forkJoin(您需要添加import 'rxjs/add/observable/forkJoin'):

Observable.forkJoin([
  this.userData.getUserPhotos(),
  this.userData.getUserInfo()]).subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});

Typescript相关问答推荐

为什么仅对对象而不对简单类型需要满足?

为什么TypScript对条件函数类型和仅具有条件返回类型的相同函数类型的处理方式不同?

如何使用TypScript和react-hook-form在Next.js 14中创建通用表单组件?

返回对象的TypScript构造函数隐式地替换This的值来替换super(.)的任何调用者?

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

HttpClient中的文本响应类型选项使用什么编码?''

React typescribe Jest调用函数

仅针对某些状态代码重试HTTP请求

在分配给类型的只读变量中维护const的类型

使用订阅时更新AG网格中的行

CDK从可选的Lambda角色属性承担角色/复合主体中没有非空断言

在另一个类型的函数中,编译器不会推断模板文字类型

TypeScrip中的类型安全包装类

如何使这种一对一关系在旧表上起作用?

使用Type脚本更新对象属性

如何在打字角react 式中补齐表格组

编剧- Select 下拉框

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

如何在TypeScript中声明逆变函数成员?

可选通用映射器函数出错