如何解析另一个Observable中的Observable? - rxjs

时间:2015-12-09 23:00:20

标签: javascript rxjs

我有一个Observable我在其中消耗了另一个可观察量,但第二个Observable我无法解决。这是代码:

return Observable.fromPromise(axios(config))
        .map(res => {
            return {
                accessToken: res.data.access_token,
                refreshToken: res.data.refresh_token                
            }
        })
        .map(res => {
            return {
                me: getMe(res.accessToken),
                accessToken: res.accessToken,
                refreshToken: res.refreshToken                
            }
        })

function getMe(accessToken) {
    return Observable.fromPromise(axios.get({
        url: 'https://api.spotify.com/v1/me',
    }));
}

getMe函数返回Observable,但它永远不会被解析。我尝试添加flatMapconcat,但仍未解决。如何让getMe解决?

3 个答案:

答案 0 :(得分:8)

Did you try the following (Also untested):

function getMe(accessToken) {
  return Rx.Observable.fromPromise(axios.get({
    url: 'https://api.spotify.com/v1/me',
  }));
}    

Rx.Observable.fromPromise(axios(config))
    .map((res) => {
        return {
            accessToken: res.data.access_token,
            refreshToken: res.data.refresh_token                
        }
    })
    .flatMap((res) => {
        return getMe(res.accessToken).map((res2) => {
          res.me = res2;
          return res;
        }
    })
    .subscribe((data) => console.log(data));

As mentioned in the above post, flatMap returns an observable. map is subsequently used to merge res with the result res2 returned from the second promise.

Also note that fromPromise is a cold observable. This means that you must have a subscription to initiate things. In your case, I presume you already have something like this:

someFunction = () => {
  return Rx.Observable.fromPromise(axios(config))
     ...
     ...
}

someFunction.subscribe((data) => console.log(data));

答案 1 :(得分:2)

As @user3743222 pointed out, an Observable does not resolve in the sense that a Promise does. If you want the value you of the getMe method you will need to subscribe to the Observable returned by it.

return Observable.fromPromise(axios(config))
        .map(res => {
            return {
                accessToken: res.data.access_token,
                refreshToken: res.data.refresh_token                
            }
        })
        .flatMap(function(tokens) {

          //FlatMap can implicitly accept a Promise return, so I showed that here
          //for brevity
          return axios.get({url : 'https://api.spotify.com/v1/me'});
        },

        //The second method gives you both the item passed into the first function
        //paired with every item emitted from the returned Observable`
        //i.e. axios.get(...)
        function(tokens, response) {
          return {
            accessToken: tokens.accessToken,
            refreshToken: tokens.accessToken,
            //Here response is a value not an Observable
            me: response
          };
        });

答案 2 :(得分:0)

下面找到的示例代码(UNTESTED !!)。一些解释:

  • getMe返回的可观察量未被展平('解决'属于承诺的世界),因为map运算符不会使可观察对象变平。 flatMap会这样做,但您需要以source.flatMap(function(x){return observable})的形式使用它,此处您返回的是POJO而不是Rx.Observable
  • 因此,为了展平getMe我们使用flatMap
  • 要添加缺少的字段(accessTokenrefreshToken),我们会在发出withLatestFrom对象(res)的观察者身上使用res$。< / LI>
  • 我们在share订阅两次时使用res$,我们希望所有订阅者都能看到相同的值。

    var res$ = Observable
      .fromPromise(axios(config))
      .map(function ( res ) {
           return {
             accessToken  : res.data.access_token,
             refreshToken : res.data.refresh_token
           }
         })
      .share();
    var getMe$ = res$.flatMap(function ( res ) {return getMe(res.accessToken)});
    var finalRes$ = getMe$.withLatestFrom(res$, function ( getMe, res ) {
    return {
       me           : getMe,
       accessToken  : res.accessToken,
       refreshToken : res.refreshToken
     }
    });
    
    function getMe ( accessToken ) {
      return Observable.fromPromise(axios.get({url : 'https://api.spotify.com/v1/me'}));
    }