使用另一个observable更改observable的订阅状态

时间:2017-02-19 03:23:29

标签: javascript angular rxjs rxjs5

如果您运行下面的代码,您将在控制台中看到发送xhr请求,无论我是subscribed还是subject。我不想在没有这个要求时提出这些要求。

// 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而不是直接在observable上订阅的原因是因为我想在重新订阅时立即获取最后一个xhr请求的最后一个值。

2 个答案:

答案 0 :(得分:1)

您应该使用.ShareReplay(1)而不是BehaviourSubject。这样你可以保持懒惰并缓存xhr调用的最后一个值。

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

source.subscribe(console.log)

答案 1 :(得分: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));

值得注意的是,如果每个人在订阅时都.take(1),那么这将不会按预期工作,因为每个人都会获得ReplaySubject中的值,然后在新的xhrRequest之前立即取消订阅。

即。有些东西需要保持活着足够长的间隔才能继续射击。