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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:41:43  来源:igfitidea点击:

How to do the chain sequence in rxjs

javascripthttptypescriptangularrxjs

提问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 thenfor observables would be flatMap. You can see some examples of use here :

等价于thenfor observables 将是flatMap. 您可以在此处查看一些使用示例:

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 flatMapyou will need to return a promise or an observable.

注意你的函数返回的类型,因为链接 observablesflatMap需要返回一个 promise 或一个 observable。

回答by Thierry Templier

If dosthelseor dosanotherthingreturns a raw value, the operator to use is map. If it's an observable, the operator is flatMap(or equivalent).

如果dosthelsedosanotherthing返回原始值,则要使用的运算符是map。如果它是可观察的,则操作符是flatMap(或等效的)。

If you want to do something imperatively. I mean outside the asynchronous processing chain, you could leverage the dooperator.

如果你想做一些势在必行的事情。我的意思是在异步处理链之外,您可以利用do运算符。

Assuming that dosthelsereturns an observable and dosanotherthinga 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();
  });
}