如何在rxjs中执行链序列

时间:2016-06-10 12:24:50

标签: javascript http typescript angular rxjs

我想要像:

this._myService.doSomething().subscribe(result => {
  doSomething()
});
.then( () => dosthelse() )
.then( () => dosanotherthing() )

所以我想链接。然后像承诺一样。我如何在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();
});
}

3 个答案:

答案 0 :(得分:55)

可观察量的flatMap相当于this._myService.doSomething() .flatMap(function(x){return functionReturningObservableOrPromise(x)}) .flatMap(...ad infinitum) .subscribe(...final processing) 。您可以在此处查看一些使用示例:

对于您的示例,您可以执行以下操作:

flatMap

注意你的函数返回的类型,以及使用// Every other controller in my bundle extends this one class Controller extends SymfonyController { public function setContainer(ContainerInterface $container = null) { parent::setContainer($container); $this->containerInitialized(); } protected function containerInitialized() { // Initialize my.service before running action of every page try { $this->get('my.service'); } catch (SomeException $ex) { // I want redirection to happen here } } } 链接observable,你将需要返回一个promise或一个observable。

答案 1 :(得分:10)

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

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

假设dosthelse返回一个可观察的dosanotherthing原始对象,您的代码将是:

this._myService.doSomething()
  .do(result => {
    doSomething();
  })
  .flatMap( () => dosthelse() )
  .map( () => dosanotherthing() );

请注意,如果返回subcribe方法的返回值,它将对应于订阅对象而不是observable。订阅对象主要是为了能够取消observable并且不能参与异步处理链。

事实上,大部分时间,您都在链的末尾订阅。

所以我会这样重构你的代码:

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

答案 2 :(得分:-8)

我们可以使用toPromise方法,它允许您将Observable序列转换为Promise。