RxJS在第一次成功时调用第二个操作

时间:2016-04-06 04:17:53

标签: rxjs observable chaining

我正在使用Angular2和rxjs。

我有一个名为login()的操作。这将使用http.post请求将身份验证详细信息发送到服务器,然后再接收令牌。

它需要读取结果,如果成功接收到令牌,它将执行一些操作来验证令牌并对其进行解码,如果所有这些都正常,那么它将从令牌发送用户名到服务器http.get并检索用户的详细信息。

我希望以上所有内容都作为一个Observable返回,但是我很想知道应该如何使用RxJS方式一个接一个地进行两个操作。

我不认为订阅第一个操作然后在第一个操作中调用第二个操作是“正确”的方式,因为那么你如何捕获第一个操作中的失败。

这样的东西?

this.http.post('http://localhost/auth/token', creds, {
    headers: headers
})
.map(res => res.json())
.do(
    // validate token
    // decode token
)
.thenDo(
    // get user details
    this.http.get(url, options)
    .map(res => res.json())
    .do(
         //save user and token in localStorage
    )
)

2 个答案:

答案 0 :(得分:0)

我不太了解Rxjs do and thenDo功能,但是你可以这样做

 this.http.post('http://localhost/auth/token', creds, {
        headers: headers
    })
    .map(res => {
        return [{status: res.status , json: res.json()}]
        })
    .subscribe(res=>{
        if(res[0].status == 200){   // do you action depends on status code you got assuming 200 for OK response
            this.validateToken()  // Validate your token here in some  method named as validateToken
            this.decodeToken()  // decode token here in this method
            this.getUserDetail() //if everything worked fine call your another get request in another method 
        }
        },
        err => {
            console.log(err, err.status)    //catch your error here 
        })

        getUserDetail(){
            // make http get request for user detail and saveing into locastroage
        }

答案 1 :(得分:0)

使用flatMap是链接每个返回新Promise或Observable的操作的好方法。每次我们需要映射一个返回Promise或Observable的函数时,我们可以使用flatMap来构造一个发出已解析数据的流。这里我们构造一个Observable of user data,最后我们可以订阅它(保存到localstorage等)。

我假设您的验证代码只是一些返回Promise或Observable的函数。

const options = { headers };
const user$ = this.http.post('http://localhost/auth/token', creds, options)
  .map(res => res.json())
  .flatMap(validationFunctionThatReturnsAPromise)
  .flatMap(authResponse => {
    // get user details
    return this.http.get(url, options).map(res => res.json());
  });

user$.subscribe(user => /** do something with the user data **/);