javascript 如何在另一个 Observable 中解析一个 Observable?- rxjs
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34190650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I resolve an Observable inside of another Observable? - rxjs
提问by jhamm
I have an Observablein which I consume another observable, but the 2nd ObservableI can't get to resolve. Here is the code:
我有一个Observable我使用另一个 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',
}));
}
The getMefunction returns an Observable, but it is never resolved. I have tried to add a flatMapand a concat, but it still isn't resolved. How do I get the getMeto resolve?
该getMe函数返回一个Observable,但它永远不会被解析。我试图添加 aflatMap和 a concat,但仍然没有解决。我该getMe如何解决?
回答by Jeremy
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, flatMapreturns an observable. mapis subsequently used to merge reswith the result res2returned from the second promise.
如上flatMap一篇文章所述,返回一个可观察的对象。map随后用于res与res2第二个承诺返回的结果合并。
Also note that fromPromiseis 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:
另请注意,这fromPromise是一个冷的 observable。这意味着您必须订阅才能启动。在你的情况下,我想你已经有了这样的东西:
someFunction = () => {
return Rx.Observable.fromPromise(axios(config))
...
...
}
someFunction.subscribe((data) => console.log(data));
回答by paulpdaniels
As @user3743222 pointed out, an Observabledoes not resolvein the sense that a Promisedoes. If you want the value you of the getMemethod you will need to subscribe to the Observablereturned by it.
正如@user3743222 指出的那样, anObservable不像resolveaPromise那样。如果您想要该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
};
});
回答by user3743222
Sample code to find below (UNTESTED!!). Some explanations :
下面的示例代码(未经测试!!)。一些解释:
- the observable returned by
getMeis not flattened ('resolve' belong to the world of promises) because themapoperator does not flatten observables.flatMapdo, but you need to use it in the formsource.flatMap(function(x){return observable})and here what you return is aPOJOnot aRx.Observable. - So, to flatten the
getMewe use aflatMap. - To add back the missing fields (
accessTokenandrefreshToken) we usewithLatestFromon the observable who emitted theresobject (res$). We use
shareas we subscribe twice tores$, and we want all subscribers to see the same values.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'})); }
- 返回的 observable
getMe没有扁平化('resolve' 属于 promise 的世界),因为map操作符没有扁平化 observables。flatMap做,但你需要在表单中使用它,在source.flatMap(function(x){return observable})这里你返回的是一个POJOnot aRx.Observable。 - 因此,为了展平
getMe我们使用flatMap. - 为了添加缺失的字段(
accessToken和refreshToken),我们withLatestFrom在发射res对象的可观察对象上使用(和res$)。 我们使用
shareas 我们订阅了两次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'})); }

