【问题标题】:How to make multple function calls to each element in observable stream return observable stream of "new" objects如何对可观察流中的每个元素进行多个函数调用返回“新”对象的可观察流
【发布时间】:2020-07-20 19:55:52
【问题描述】:

我有一个表达式,它接受一个可观察的帖子流,并为每个帖子评估一个“posterName”并合并回原始帖子。

在返回帖子之前,有没有办法调用另一个函数来评估第二个属性(当前用户是否喜欢帖子),然后将其与海报名称和原始帖子合并。

请看下面的代码和评论

this.fService.postList$.pipe( 
      switchMap(_posts => { // switchMap to subscribe to inner

        const getUsers$ = _posts
          .map(post => // array map comments into posterName fetch
      
            this.fService.getUserName(post.uid).pipe(
              // once you have the username, rx map back into the comment with the username assigned
              map(userName => ({...post, posterName: userName.first_name + " " + userName.last_name})),

              catchError((err) => {
                // Handle specific error for this call
                console.log(err)
                return of({...post, posterName: "Anonymous"})
              }),

              first()
            )

            //Where can I write a second function that takes the same posts ID
            //and return a promise that I can "then" so I merge the resolved
            //value in to the post i.e ({...post,posterName: somename , thirdThing: somevalue}) 
        )

    

        return forkJoin(...getUsers$); // forkJoin them all together for parallel execution
      })).subscribe(data => { //doing stuff})

【问题讨论】:

    标签: angularjs promise rxjs observable


    【解决方案1】:

    这与您正在寻找的内容接近吗?

    它获取所有帖子,对于每个帖子,它获取用户和所有待办事项。

    • 它首先检索所有帖子。然后它管道检索到 通过switchMap 发帖以展平结果。

    • 它使用 forkJoin 来合并每个帖子的结果。

    • 它第二次使用 forkJoin 来合并 帖子和他们的待办事项(在你的场景中他们会喜欢)。

    • 然后它将 forkJoin 的结果映射到一个结构中,该结构由
      该用户的帖子、用户名和待办事项列表。

    • 模板使用异步管道订阅 postData$
      结构并访问该结构的所需部分。

    注意:这与您的代码不完全相同,因为我使用了公共用户/帖子/待办事项 API,因此我可以确保以下代码正常工作。

      // Get all posts
      // Get the user of each post
      // Get the todos for each user
      postData$ = this.http.get<Post[]>(this.postUrl).pipe(
        switchMap(posts =>
          forkJoin(
            posts.map(post =>
              forkJoin([
                this.http.get<User>(`${this.userUrl}/${post.userId}`),
                this.http.get<ToDo[]>(`${this.todoUrl}?userId=${post.userId}`)
              ]).pipe(
                map(([user, todos]) => ({
                  post: post,
                  userName: user.name,
                  todos: todos
                }))
              )
            )
          )
        )
      );
    
    
    export interface Post {
      userId: number;
      id: number;
      title: string;
      body: string;
    }
    
    export interface ToDo {
      userId: number;
      id: number;
      title: string;
      completed: boolean;
    }
    
    export interface User {
      id: number;
      name: string;
      username: string;
      email: string;
      website: string;
    }
    
    export interface PostData {
      post: Post;
      userName: string;
      toDos: ToDo[];
    }
    

    我在这里有一个堆栈闪电战:https://stackblitz.com/edit/angular-todos-posts-forkjoin-deborahk

    【讨论】:

    • 非常感谢!好像我很接近了,但可观察对象没有完成。在哪里添加“first()”来强制完成内部可观察对象?
    • 等等!!!!天哪,你是黛博拉仓田!我真的是在用你的 Angular:PluralSight 入门课程在我身边做这件事!!!大粉丝!!
    • 谢谢!如果这些正在检索数据,那么它们将在不需要执行 .first() 的情况下完成。如果您正在做其他事情,请随时 fork 我的 stackblitz 并对其进行修改以更紧密地展示您的问题/问题。
    • 我已编辑您的回复以反映我当前的问题。我没有收到任何错误,但 subscribe 方法上的完整函数永远不会被调用。我知道在我明确调用 take(1)/first() 之前,我的 firebase observables 没有完成
    • 30 分钟后,我设法让它工作了!谢谢黛博拉!!答案已更新
    猜你喜欢
    • 1970-01-01
    • 2017-07-12
    • 2019-02-18
    • 2011-06-17
    • 2018-12-16
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多