2017-06-14 94 views
1

我创建了一项服务,它使用RxJS来包装$http调用。Angular 1服务 - RxJS共享运营商不能正常工作

我有几个组件订阅相同的observable,我希望他们共享AJAX结果,而不是多个请求。

服务代码:

export function SearchService($http) { 
    'ngInject'; 

    const autocompleteResults$ = new Subject() 
     .debounceTime(250) 
     .switchMap(query => Observable.fromPromise($http.post('/search', { query }))) 
     .share() 
     .map(result => result.data); 


    function autocomplete(query) { 
     autocompleteResults$.next(query); 
    } 

    return { 
     autocomplete, 
     autocompleteResults$ 
    }; 
} 

组件的代码:

export const myComponent = { 
    bindings: { 
     query: '<' 
    }, 
    templateUrl: templateUrl, 
    controller: myController 
}; 

function myController($SearchService) { 
    'ngInject'; 
    const $ctrl = this; 

    $ctrl.$onInit = $onInit; 
    $ctrl.$onChanges = $onChanges; 

    function $onInit() { 
     SearchService.autocompleteResults$ 
      .subscribe(
       handleSuccess, 
       handleError 
      ); 
    } 

    function $onChanges(changes) { 
     if (changes.query && changes.query.currentValue) 
      SearchService.autocomplete(changes.query.currentValue); 
    } 
} 

我有,要查询的变化做出反应的myComponent活性组分。

由于Angular服务是单身,每个组件应该得到订阅它的时候,却总是有相同的观察到的实例2 AJAX调用,而不是1

我使用sharepublishpublishReplayshareReplay尝试和refCount运营商没有成功。

回答

1

你所描述的看起来更像是你正在寻找缓存而不是共享和Observable。

当您使用share()时,您只是将共享的订阅与其源Observable共享,而不是其结果。

例如,如果一个HTTP请求需要100毫秒,那么这将让两个请求使用share()即便:

const source = this.http.get(...).share(); 
source.subscribe(...); 

setTimeout(() => source.subscribe(...), 1000); 

share()运营商不帮助你在这里,因为在所有的第一个HTTP请求完成后观察员取消订阅,share()内的主题也取消订阅。然后,在1秒后,您再次订阅,并需要重新订阅,这会再次发出HTTP请求。

但是,如果你做了以下那么你会做只有一个HTTP请求:当第二观察者签约第一个是仍处于活动状态,并且通过share()被播

const source = this.http.get(...).share(); 
source.subscribe(...); 
source.subscribe(...); 

。因此,您只需进行一次HTTP调用。

也许你正在寻找的东西像这样的重放1秒接收值:

const source = this.http.get(...) 
    .publishReplay(1, 1000) 
    .refCount() 
    .take(1);