简体   繁体   English

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

[英]How do I resolve an Observable inside of another Observable? - rxjs

I have an Observable in which I consume another observable, but the 2nd Observable I can't get to resolve. 我有一个Observable ,我在其中消耗了另一个observable,但第二个Observable我无法解决。 Here is the code: 这是代码:

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',
    }));
}

The getMe function returns an Observable , but it is never resolved. getMe函数返回一个Observable ,但它永远不会被解析。 I have tried to add a flatMap and a concat , but it still isn't resolved. 我试图添加一个flatMap和一个concat ,但它仍然没有解决。 How do I get the getMe to resolve? 如何解决getMe问题?

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. 如上面的帖子所述, flatMap返回一个observable。 map is subsequently used to merge res with the result res2 returned from the second promise. map随后用于将res与从第二个promise返回的结果res2合并。

Also note that fromPromise is a cold observable. 另请注意, fromPromise是一个寒冷的fromPromise 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));

As @user3743222 pointed out, an Observable does not resolve in the sense that a Promise does. 正如@ user3743222指出的那样, ObservablePromise的意义上没有resolve If you want the value you of the getMe method you will need to subscribe to the Observable returned by it. 如果你想要getMe方法的值,你需要订阅它返回的Observable

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
          };
        });

Sample code to find below (UNTESTED!!). 下面找到的示例代码(UNTESTED !!)。 Some explanations : 一些解释:

  • the observable returned by getMe is not flattened ('resolve' belong to the world of promises) because the map operator does not flatten observables. getMe返回的getMe不会被getMe平('resolve'属于promises的世界),因为map运算符不会展平observable。 flatMap do, but you need to use it in the form source.flatMap(function(x){return observable}) and here what you return is a POJO not a Rx.Observable . flatMap do,但你需要以source.flatMap(function(x){return observable})的形式使用它,这里你返回的是POJO而不是Rx.Observable
  • So, to flatten the getMe we use a flatMap . 因此,为了展平getMe我们使用flatMap
  • To add back the missing fields ( accessToken and refreshToken ) we use withLatestFrom on the observable who emitted the res object ( res$ ). 要添加缺少的字段( accessTokenrefreshToken ),我们在发出res对象( res$ )的observable上使用withLatestFrom
  • We use share as we subscribe twice to res$ , and we want all subscribers to see the same values. 我们使用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'})); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM