连接两个可观察对象以通过 id 查找名称

Connect two observables to find name by id

我有 2 个端点:

users = [
 {
   id: 1,
   name: 'Mark',
   companyId: 1
 },
 {
   id: 2,
   name: 'Jack',
   companyId: 1
 },
]
companies = [
 {
   name: 'Facebook',
   id: 1
 }
]

现在,我如何构建我的观察者以获取每个用户的公司名称?所以在我的 html 中,我可以做例子。 user.company.name

我现在的get方法: baseUrl 是 localhost:3000/users

  getUsers(): Observable<IUser[]> {
    return this.http.get<IUser[]>(this.baseUrl).pipe(
      share()
    );
  }

使用forkJoin并行获取用户和公司数据,然后将结果映射为所需类型。

forkJoin([
    this.http.get<IUser[]>(this.baseUrl + '/users'),
    this.http.get<IComapany[]>(this.baseUrl + '/comapnies')
]).pipe(map(([users, companies]) => users.map(user => 
    {
      return {
        "id": user.id,
        "name": user.name,
        "company": companies.find(x=> x.id == user.companyId)
      } 
    })
))

示例:https://stackblitz.com/edit/rxjs-wkdn3r

简短的回答是 forkJoin

示例:

const usersObservable = this._http.get('https://example/api/users');
const companiesObservable = this._http.get('https://example/api/companies');

const usersAndCompanies = Observable.forkJoin([usersObservable, companiesObservable])
  .subscribe(
     result => return this._joinUsersAndCompanies(result) 
  );


private _joinUsersAndCompanies(result) {

  const users = result[0];
  const companies = result[1];

  return users.map(user => {

    const matchedCompany = companies.find(company => company.Id === user.companyId);
    
    return {
      ...user,
      companyName: matchedCompany!.name
    };

  });
}

这只是一个草稿,我不确定这是否会编译并 运行 正确,但我希望你明白了。

如果你需要经常从API获取用户和公司或者return数据很大,你可以通过先将const companies转换并存储在地图中进行优化,这样您可以在恒定时间内访问它们 bigO(1).