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 Observable
in which I consume another observable, but the 2nd Observable
I 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 getMe
function returns an Observable
, but it is never resolved. I have tried to add a flatMap
and a concat
, but it still isn't resolved. How do I get the getMe
to 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, flatMap
returns an observable. map
is subsequently used to merge res
with the result res2
returned from the second promise.
如上flatMap
一篇文章所述,返回一个可观察的对象。map
随后用于res
与res2
第二个承诺返回的结果合并。
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:
另请注意,这fromPromise
是一个冷的 observable。这意味着您必须订阅才能启动。在你的情况下,我想你已经有了这样的东西:
someFunction = () => {
return Rx.Observable.fromPromise(axios(config))
...
...
}
someFunction.subscribe((data) => console.log(data));
回答by paulpdaniels
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.
正如@user3743222 指出的那样, anObservable
不像resolve
aPromise
那样。如果您想要该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
getMe
is not flattened ('resolve' belong to the world of promises) because themap
operator does not flatten observables.flatMap
do, but you need to use it in the formsource.flatMap(function(x){return observable})
and here what you return is aPOJO
not aRx.Observable
. - So, to flatten the
getMe
we use aflatMap
. - To add back the missing fields (
accessToken
andrefreshToken
) we usewithLatestFrom
on the observable who emitted theres
object (res$
). We use
share
as 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})
这里你返回的是一个POJO
not aRx.Observable
。 - 因此,为了展平
getMe
我们使用flatMap
. - 为了添加缺失的字段(
accessToken
和refreshToken
),我们withLatestFrom
在发射res
对象的可观察对象上使用(和res$
)。 我们使用
share
as 我们订阅了两次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'})); }