Rx debounce operator with first and last

南笙酒味 提交于 2019-12-21 11:28:10

问题


Is there any combination of rx operators so as to get the first and last debounced event?

This is going to be used in master detail scenarios (or even seach scenarios) where we want immediate loading of first selected item and the last after user stops changing selection.

This would prevent the debounce time to be injected when the user navigates slowly but also prevent bursts of changes.

If debounce operator had an option "immediate" like underscore.js debounce functoin then a merge of the 2 versions of debounce operator would generate the needed result.


回答1:


To get the the first debounced element, you can use throttle. To get the last, you can use debounce. You however should make sure that the source you are debouncing or throttling is a hot source as you will apply both operators to the same source. Then if you want both elements in the same observable, then you can just merge the throttled and debounced streams.

For example, calling source$ your source observable:

firstAndLast$ = Rx.Observable.merge(source$.debounce(Xms), source$.throttle(Xms))

This should issue the first item and the last item of a burst in the same stream. Note that in the edge case that this is not a burst but a single value that is occuring within the Xms time period, you might have twice the same value, one at the beginning of the period, and one at the end. A way to protect against that, if that makes sense is to use distinctUntilChanged, so this becomes:

firstAndLast$ = Rx.Observable.merge(source$.debounce(Xms), source$.throttle(Xms)).distinctUntilChanged()



回答2:


Just combining the throttle and debounce as suggested in the previous answer was not enough for me because it periodically emits new events when the throttle time runs out.

const debounced$ = source$.debounceTime(time)
return source$.throttleTime(time)
  .merge(debounced$).distinctUntilChanged()

With a time=30 you would get:

-a-a-a-a-a-a----
-a---a---a----a-

To only get the first and last event with a minimum time in between I used:

const debounced$ = source$.debounceTime(time)
return source$.throttle(() => debounced)
  .merge(debounced$).distinctUntilChanged()

Which results in:

-a-a-a-a-a-a----
-a------------a-



回答3:


A hybrid operator with UX-friendly behavior: https://www.npmjs.com/package/rx-op-debounce-throttle

Emits first and last items in the batch, plus as much as possible events within the window, separated by at least X ms.



来源:https://stackoverflow.com/questions/35957168/rx-debounce-operator-with-first-and-last

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