Postpone observable when other one fired in RxJs

梦想的初衷 提交于 2019-12-12 00:42:00

问题


I have a table on a page and two subscriptions:

  1. First one reloads table data. It has a delay because it calls an api.
  2. Second highlights data. Does not affect table data.

When subscriptions fire one by one everything is OK, but when they fire at the same time data is highlighted and soon after is reloaded so highlighting is gone.

You can see it here.

Is there are way to postpone highlighting if reloading is in action?

Probably I can accomplish this by introducing loading variable but I am looking for reactiveX solution.

Thanks in advance.


回答1:


Keep in mind that in rxjs everything is a stream, which you can use to your advantage, I've modified you fiddle a bit so that everything is a stream now:

  var pageClicks = Rx.Observable.fromEvent(document.getElementById('page'),  'click');
  var highlightClicks = Rx.Observable.fromEvent(document.getElementById('highlight'), 'click');
  var bothClicks = Rx.Observable.fromEvent(document.getElementById('both'), 'click');

  var page = 0;
  var nextPage$ = Rx.Observable.of(page)
    .map(function() {
      page = (page + 1) % 2;
      return page
    })
    .switchMap(loadData)
    .do(renderData);

  var doBoth$ = nextPage$
    .do(highlight);

  // initial rendering of data
  doBoth$.subscribe();

  pageClicks
    .switchMapTo(nextPage$)
    .subscribe();

  highlightClicks
    .do(highlight)
    .subscribe();

  bothClicks
    .switchMapTo(doBoth$)
    .subscribe();

Here is the link to the updated fiddle: https://fiddle.jshell.net/r2L7k0mc/3/


Based on your comments I have updated your fiddle with the following code:

  var page$ = events.page$.share();
  var loadData$ = page$
    .startWith(0)
    .switchMap(page => loadData(page).takeUntil(page$))
    .do(renderData);
  loadData$.subscribe();

  var loading$ = Rx.Observable.merge(
    page$.mapTo(true),
    loadData$.mapTo(false)
  )
    .startWith(false)
    .publishReplay(1);
  loading$.connect();

  events.highlight$
    .switchMap(function() {
        return loading$
        .filter(function(isLoading) { return !isLoading; })
        .take(1);
    })
    .do(highlight)
    .subscribe();

See: https://fiddle.jshell.net/mc8h52r7/5/

However I would strongly suggest to rethink the architecture, since this is a very ugly set of streams, that could surely be optimized with a different architecture.



来源:https://stackoverflow.com/questions/40636035/postpone-observable-when-other-one-fired-in-rxjs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!