2017-09-21 11 views
0

내 Angular 앱에서 알림 작업 중이며 최신 사용자의 알림을 요청하는 REST API가 있습니다. 사용자가 실시간으로 알림을받는 것이 중요하지 않기 때문에이 API를 몇 분 만에 호출해야합니다 (아마 그렇게 빨리 표시되지는 않습니다). 클라이언트 측이 옆에 아이디어 알림을 새로 고치려면 그러나 :수동으로 호출 할 때 간격으로 RxJS 폴링

  • 때 시작 상쾌한 통지에 사용자가 로그인 - 여기 몇 분
    • 사용자가 응용 프로그램을 벗어나면 에 API를 상쾌하게 시작하는 최초의 수동 호출입니다 열려 있거나 타이머를 변경하지 않고 나머지 시간 동안 기다리십시오.
    • 알림과 관련된 작업을 수행 할 수있는 서브 페이지를 열고 알림을 새로 고치고 타이머를 재설정하면
  • 로그 아웃

까지

  • 새로 고침 알림 이미 설명 된 절차에 대한 코드를 작동해야하지만 나는 내가 필요에 대한 올바른 있다고 어떻게 든 확실 해요. 여기에 통화를 수행하기위한 코드 (수동 검사에 대한 그냥 주제 거기 거기 관찰에 가입입니다 확인 정지를위한 - 아래 실제로 분리되는 코드는, 그러나 여기 때문에 가독성을 한 장소에) :

    // Subject for manual triggering 
    this.checkFeed = new Subject<void>(); 
    
    // Call for refresh in own method 
    this.checkFeed.next(); 
    
    // Waiting for manual refresh or triggering it on some interval after it was last triggered 
    this.feedSub = this.checkFeed.asObservable() 
         .switchMap(() => Observable.timer(0, this.interval)) 
         .mergeMap(() => this.fetchChanges()) 
         .distinctUntilChanged(this.compareFeed) 
         .subscribe(res => this.notify(res)); 
    
    // Unsubscription when logging out 
    if (this.feedSub) this.feedSub.unsubscribe(); 
    

    가장 확실하지 않은 부분은 .switchMap(() => Observable.timer(0, this.interval))입니다. 바로 시작하려면 0이 필요합니다. (그래도 괜찮습니까?). 제가 묘사 한 것을 성취 할 수있는 더 좋은 방법이 있습니까?

    다른 관찰 가능 항목에서 알림을 확인하는 방법 - 어떤 연산자를 사용해야합니까?

    refreshFeed(): void { 
        this.checkFeed.next(); 
    } 
    

    그래서 다른 관찰 수행이있을 때 (액션 통지가 갱신되어야 할 때) 나는이 하나를 호출해야합니다 내가 언급 한 바와 같이 나는 제목의 자신의 방법에서 다음과 같이에 전화를합니다. void 메서드를 호출하는 올바른 방법은 다른 관찰 가능 함수가 API로부터 응답을 받았을 때입니까? 나는 이런 식으로 생각하고 있었다.

    someActionThatCanChangeNotifications(): Observable<any> { 
        return this.api.get('path/to/endpoint') 
        .do(() => this.feedService.refreshFeed()); 
    } 
    

    괜찮 냐, 아니면 더 좋은 방법이 있을까?

    미리 도움을 청하십시오!

  • 답변

    0

    그래서 기본적으로 두 가지를 관찰 할 수 있습니다. 수동으로 전화

    하나 :

    this.checkFeed 
    

    와의 간격을 (의이 intervalObs을 callit하자) :이처럼 보이면

    this.intervalObs = Observable.timer(0, this.interval); 
    

    는 easyest 방법은 you'r 두 개의 소스를 병합하는 것입니다 스트림을 누른 다음 원하는대로 수행하십시오.

    var mergedSource = Observable.merge(
        this.checkFeed, 
        this.intervalObs) 
    
    subscription = mergedSource.subscribe(this.fetchChanges()); 
    

    사이에 더 많은 작업을 수행해야 할 수도 있지만 더 읽기 쉬운 대안을 제공해야합니다.당신이 뭔가 난 당신이 꽤 많이 "제대로"그것을 한 적이 볼 수있는에서 arround를 https://plnkr.co/edit/n4nNFEMa4YOh2KSjDpSJ?p=preview

    +0

    간격을 5 초 (plunker)로 설정하고 간격의 중간을 클릭하면 (이벤트가 발생할 때까지 2 ~ 3 초가 남아있을 때) 관찰 할 수있는 항목을 병합하는 것이 좋지 않습니다. 5 초로 재설정하지 않고 나머지 시간 (앞서 말한 2 또는 3 초) 후에 방출합니다. – user1257255

    0

    재생하려면

    는이 작업 plunker을 시도 할 수 있습니다. 일반적으로 프로그래밍과 마찬가지로 단일 문제에 대해 가능한 많은 해결책이 있습니다. 개인적으로, 나는 이것을 똑같이 할 것입니다.

    난 당신이 너무 언급 한 두 점 몇 가지 논평을 제공 할 수 있습니다 :

    .switchMap(() => Observable.timer(0, this.interval))

    Observable.timer

    거의 첫 번째 값 전에 사용자 정의 시간 제한과 Observable.interval. Observable.timer(0, this.interval)이 올바른 사용법입니다.

    Observable.just(0).concat(Observable.interval(this.interval)) 대안은 즉시 값을 반환 한 다음 해당 간격을 시작합니다. 나는 그러나 당신이 두는 방법을 선호한다; 나는 당신의 의도를 명확하게 진술했다고 생각한다 : "0 밀리 세컨드 후에 값을 그리고 나서 this.interval 간격을 만들어라."

    .do(() => this.feedService.refreshFeed())

    나는이 그 일의 완전히 올바른 방법이다라고 말하고 싶지만. do은 부작용을 의미합니다. 그런 일이 일어나면 바깥쪽으로 관찰 할 수 있습니다.

    내가 말할 수 있지만, 나는 someActionThatCanChangeNotifications 먹이 새로 고침을 시작할 것을 기대하지 않을 것이다. 함수가 observable을 반환하면, 부작용이없는 observable을 반환 할 것으로 기대합니다. 그러나 우리가 완전하지 않은 세상에 살면서 우리는 항상 원하는 것을 가질 수는 없습니다.

    모든 구독자가 .do(() => this.feedService.refreshFeed())을 기억해야한다는 것을 기대할 수는 없지만 대신 함수에 대한 문서 주석에 "메모 : 반환 된 관찰 가능 항목은 다음 신호마다 피드를 새로 고침"또는 그런 종류의.