通过Observable过滤可观察的

时间:2015-06-11 15:39:47

标签: javascript frp rxjs

如果其他Observable产生Observable.subscribe(),我想确保true没有被执行。

示例用例将确保用户只有在前一个用户完成(或失败)并且一次只执行一个下载请求时才能触发下载。

为了控制执行流程,我不得不依赖一个对我来说有点奇怪的状态变量 - 这是一个好的模式吗?在一个可能的情况下,它不是 - 什么是更好的方法?

我最终得到了两个订阅:Actions.sync(使用主题,公共API,初始化同步请求)和isActive(解析为true或`false,名称应为非常不言自明。

let canDownload = true; // this one feels really, really naughty
const startedSyncRequests = new Rx.Subject();
const isActiveSync = startedSyncRequests.map(true)
  .merge(completeSyncRequests.map(false))
  .merge(failedSyncRequests.map(false))
  .startWith(false)
  .subscribe(isActive => canDownload = !isActive)

syncResources = ()=>{
  startedSyncRequests.onNext();
  // Mocked async job
  setTimeout(()=> {
    completeSyncRequests.onNext();
  }, 1000);
};


Actions.sync
  .filter( ()=> canDownload ) // so does this
  .subscribe( syncResources );

1 个答案:

答案 0 :(得分:2)

您想要exclusive()

Actions.sync
  .map(() => {
    //Return a promise or observable
    return Rx.Observable.defer(() => makeAsyncRequest());
  })
  .exclusive()
  .subscribe(processResults);

每次用户发出请求时,上面都会生成一个observable。但是,exclusive将丢弃在上一个完成之前进入的任何可观察对象,然后将生成的消息展平为单个可观察对象。

工作示例(使用intervaldelay):

var interval = Rx.Observable.interval(1000).take(20);


interval
  .map(function(i) {
    return Rx.Observable.return(i).delay(1500);
  })
  .exclusive()
  //Only prints every other item because of the overlap
  .subscribe(function(i) {
    var item = $('<li>' + i + '</li>');
    $('#thelist').append(item);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.3/rx.all.js"></script>
<div>
  <ul id="thelist">
  </ul>

</div>

参考:here