【问题标题】:how to combine multiple observables on first observable complete and return as new observable in method如何在第一个可观察对象上组合多个可观察对象并在方法中作为新的可观察对象返回
【发布时间】:2020-09-14 02:12:33
【问题描述】:

我是使用 RxJs 运算符的初学者,我需要一种方法,该方法从服务中调用 5 个可观察对象,并且仅在第一个可观察对象完成后才应从服务中获取数据,然后组合所有可观察对象并转换为新的observable 并在函数中返回一个新的 observable。下面的代码说明了这种情况。

GetAllDetails(): Observable<AllDetails> {

const user = this.service.getUser() // Observable<User>
const firstDetails = this.service.getFirstDetail() // returns Observable<FirstDetail>
const secondDetails = this.service.getSecondDetail() // returns Observable<SecondDetail>
const thirdDetails = this.service.getThirdDetail() // returns Observable<ThirdDetail>
const fourthDetails = this.service.getFourthDetail() // returns Observable<FourthDetail>

// need to return a value that something compatible with Observable<AllDetails>
// so the logic should check if user info available then do combining all observable values and 
// return as new observable 

return of(new AllDetails(first, second, third, fourth) 
}

我尝试使用 CombineLatest 和 switchMap,但在我的第一个 observable 完成后我无法实现这一点。感谢是否有人可以帮助我解决这个问题。

【问题讨论】:

    标签: angular rxjs-observables


    【解决方案1】:

    我相信您正在寻找的是forkJoin

    forkJoin 是最简单的方法,当您需要等待多个 HTTP 请求被解析时。

    例子:

    public fetchDataFromMultipleSources(): Observable<any[]> {
    let response1 = this.http.get(url1).subscribe((response) => {
      let response2 = this.http.get(url2);
      let response3 = this.http.get(url3);
      return forkJoin([response1, response2, response3]);
    });
    return response1;
    }
    

    【讨论】:

    • 谢谢曼尼什。但是,我想在方法中的第一个可观察对象完成后返回多个可观察对象。你能告诉我如何检查吗?
    • 你的意思是getFirstDetailgetSecondDetail等应该在this.service.getUser()完成时调用吗?
    • 感谢 Manish 的更新。我同意这也有效!但是,我尝试了@Andrei 的解决方案并因此被接受。请不要误会我。
    • 当然。很高兴知道我们的回答对您有所帮助。万事如意!
    【解决方案2】:

    你可以试试这个:

    return user.pipe(
      last(), // Get the lastest value when the `user$` completes
      switchMap(
        user => conditionOnUser 
          ? forkJoin({ first: firstDetails, second: secondDetails /* ... */ })
          : of(null)
      ),
      map(
        detailsOrNull => !detailsOrNull
          ? false // No user info available
          : new AllDetails(detailsOrNull.first, detailsOrNull.second /* ... */)
      )
    )
    

    【讨论】:

    • 谢谢安德烈。是否也可以在 AllDetails 中包含用户信息?
    • 当然,您可以为传递给forkJoin的对象添加另一个属性:forkJoin({ first: firstDetails, ..., user: of(user) })。然后,该对象在外部map中可用
    • 谢谢安德烈。我试过这个,这对我有用。抱歉回复晚了。
    猜你喜欢
    • 2017-07-12
    • 2020-02-11
    • 2019-02-18
    • 1970-01-01
    • 2018-12-16
    • 2011-06-17
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多