Rx Observable是否有周期起始发射值的Sample运算符?需自行实现吗?
周期起始时刻采样的Rx实现方案
你要的这种“周期起始时刻发射值”的采样逻辑,不需要从零开发新运算符,用RxJS现有运算符组合就能实现,下面分场景给你具体方案:
核心实现:定时起始采样
如果需求是每个固定周期的起始时刻,获取源Observable的最新值并发射(类似定时快照,不管周期内源有没有新值,到点就取当前最新的),可以用interval + withLatestFrom组合:
import { interval, Observable } from 'rxjs'; import { withLatestFrom, map, distinctUntilChanged } from 'rxjs/operators'; // 自定义采样函数:周期起始时刻发射源的最新值 function sampleOnIntervalStart<T>(source$: Observable<T>, intervalMs: number): Observable<T> { return interval(intervalMs).pipe( // 每次interval触发(周期起始),取源的最新值 withLatestFrom(source$), // 提取源的值 map(([_, value]) => value), // 可选:避免连续发射相同值,不需要可去掉 distinctUntilChanged() ); }
逻辑说明
interval(intervalMs)会在每个周期的起始点发射递增数字,相当于定时触发采样信号;withLatestFrom(source$)会在采样信号触发时,获取源Observable当前的最新值;- 最后用
map提取出源的值,就实现了周期起始时刻的采样。
和throttleTime的区别
你提到的throttleTime({ leading: true, trailing: false })虽然也会在间隔起始发射值,但它的逻辑是抑制间隔内的后续值:只有当源在间隔起始有新值到来时才发射,之后间隔内的所有值都会被忽略,直到下一个间隔开始。这和“定时采样”本质不同——采样是不管周期内源有没有新值,到点就取最新值,而throttle是只响应间隔起始的第一个值。
如果你的场景是需要严格按时间周期触发采样,用上面的interval+withLatestFrom组合更准确;如果是想抑制高频触发,只保留每个间隔的第一个值,那throttleTime(leading: true)更适合。
内容的提问来源于stack exchange,提问作者Oliver Weichhold
相关产品推荐
相关产品推荐

