Javascript 如何在rxjs中做链序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37748241/
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 to do the chain sequence in rxjs
提问by adam nowak
I would like to to something like:
我想这样做:
this._myService.doSomething().subscribe(result => {
doSomething()
});
.then( () => dosthelse() )
.then( () => dosanotherthing() )
So I would like to chain .then like in promise. How would I do that in Rxjs?
所以我想像承诺一样链接 .then 。我将如何在 Rxjs 中做到这一点?
this._myService.getLoginScreen().subscribe( result => {
window.location.href = MyService.LOGIN_URL;
/// I would like to wait for the site to load and alert something from the url, when I do it here it alerts the old one
});
.then (alert(anotherService.partOfTheUrl())
getLoginScreen() {
return this.http.get(myService.LOGIN_URL)
.flatMap(result => this.changeBrowserUrl())
.subscribe( result => //i want to do sth when the page is loaded//);
}
changeBrowserUrl(): Observable<any> {
return Observable.create( observer => {
window.location.href = myService.LOGIN_URL;
observer.next();
});
}
回答by user3743222
The equivalent of then
for observables would be flatMap
. You can see some examples of use here :
等价于then
for observables 将是flatMap
. 您可以在此处查看一些使用示例:
- RxJS Promise Composition (passing data)
- Why we need to use flatMap?
- RxJS sequence equvalent to promise.then()?
For your example, you could do something like :
对于您的示例,您可以执行以下操作:
this._myService.doSomething()
.flatMap(function(x){return functionReturningObservableOrPromise(x)})
.flatMap(...ad infinitum)
.subscribe(...final processing)
Pay attention to the types of what your functions return, as to chain observables with flatMap
you will need to return a promise or an observable.
注意你的函数返回的类型,因为链接 observablesflatMap
需要返回一个 promise 或一个 observable。
回答by Thierry Templier
If dosthelse
or dosanotherthing
returns a raw value, the operator to use is map
. If it's an observable, the operator is flatMap
(or equivalent).
如果dosthelse
或dosanotherthing
返回原始值,则要使用的运算符是map
。如果它是可观察的,则操作符是flatMap
(或等效的)。
If you want to do something imperatively. I mean outside the asynchronous processing chain, you could leverage the do
operator.
如果你想做一些势在必行的事情。我的意思是在异步处理链之外,您可以利用do
运算符。
Assuming that dosthelse
returns an observable and dosanotherthing
a raw object, your code would be:
假设dosthelse
返回一个 observable 和dosanotherthing
一个原始对象,您的代码将是:
this._myService.doSomething()
.do(result => {
doSomething();
})
.flatMap( () => dosthelse() )
.map( () => dosanotherthing() );
Notice that if you return the return of the subcribe method, it will correspond to a subscription object and not an observable. A subscription object is mainly for being able to cancel the observable and can't take part of the asynchronous processing chain.
请注意,如果您返回 subcribe 方法的返回值,它将对应于订阅对象而不是可观察对象。订阅对象主要是为了能够取消observable,不能参与异步处理链。
In fact, most of the time, you subscribe at the end of the chain.
事实上,大多数时候,你是在链的末端订阅的。
So I would refactor your code this way:
所以我会这样重构你的代码:
this._myService.getLoginScreen().subscribe( result => {
window.location.href = MyService.LOGIN_URL;
/// I would like to wait for the site to load and alert something from the url, when I do it here it alerts the old one
alert(anotherService.partOfTheUrl()
});
getLoginScreen() {
return this.http.get(myService.LOGIN_URL)
.flatMap(result => this.changeBrowserUrl())
.do( result => //i want to do sth when the page is loaded//);
}
changeBrowserUrl(): Observable<any> {
return Observable.create( observer => {
window.location.href = myService.LOGIN_URL;
observer.next();
});
}