2017-02-19 16 views
2

아래 코드를 실행하면 subscribed에서 subject인지 여부에 관계없이 xhr 요청이 전송됩니다. 내가 그 일에 굴복하지 않을 때 그 요청을하지 않기를 바란다. 내가 다시 구독 할 때 즉시 마지막 XHR 요청에서 마지막 값을 원하기 때문에관찰 가능 항목의 다른 관찰 가능 항목 변경

// npm install rxjs 
const Rx = require('rxjs/Rx'); 

let subject = new Rx.BehaviorSubject(null) 
Rx.Observable.timer(0, 1000).subscribe(i => someApiCall(i)); 
//at this point xhr request will be sent every second 

function someApiCall(i){ 
    // retrieve some data 
    console.log("xhr request sent") 
    subject.next(i); 
} 

//so here we are gonna subscribe to the subject, xhr made prior 
//to this subscription are useless 
let subscription; 
setTimeout(() => subscription = subject.subscribe(i => console.log(i)),2500); 
setTimeout(() => subscription.unsubscribe(),6000); 
// now we are unsubscribing but the xhr req keep going 

이유 나는 behaviorSubject를 사용하고 관찰에 직접 가입 아니에요이다.

+1

'Rx.Observable.timer (0, 1000) .subscribe (i => someApiCall (i));'는 결코 취소되지 않고 즉시 호출됩니다. 그래서, 저에게 "xhr request sent"메시지는 페이지가로드되는 동안 매초 기록됩니다. 그런 다음 2 xhr 메시지가 기록되면 숫자가 기록되기 시작해야하며 기록 된 4 개의 숫자 만 볼 수 있습니다. 그게 무슨 일 이니? 그것이 그 질문에 관한 것입니까? –

+0

@joe_coolish 네, 그렇게 된 것입니다. 숫자를 볼 수있을 때만 요청을 보내고 싶습니다. – Ced

답변

1

https://acutmore.jsbin.com/bepiho/2/edit?js,console

const { Observable } = Rx; 

function someApiCall(i){ 
    return Observable.create(observer => { 
    console.log("xhr request sent") 
    observer.next(i); 
    observer.complete(); 
    }); 
} 

const data = Rx.Observable.timer(0, 1000) 
    // map each value to the values of someApiCall 
    . mergeMap(i => someApiCall(i)) 
    // share the values through a replaySubject 
    .publishReplay(1) 
    // Only connect to the source when there is at least one subscriber 
    .refCount(); 

data 
    .take(5) 
    .subscribe(v => console.log(v)); 

data 
    .take(1) 
    .subscribe(v => console.log(v)); 

모두가 ReplaySubject의 값을 얻고 새로운 xhrRequest이 될 것입니다 전에 다음 즉시 취소됩니다 때문에이 가입 할 때 모든 사람이 .take(1) 않는 경우이 예상대로 작동하지 않습니다 지적 가치 만든.

즉, 뭔가 계속 유지해야합니다. 살아있을 때까지 간격이 계속 유지 될만큼 충분히 길어야합니다.

1

BehaviourSubject 대신 .ShareReplay(1)을 사용해야합니다. 그렇게하면 게으른 상태로 유지하고 xhr 호출의 마지막 값을 캐시 할 수 있습니다.

const source = Rx.Observable.interval(1000) 
    .mergeMap(I => doXhr()) 
    .shareReplay(1); 

source.subscribe(console.log) 
관련 문제