Rxjs-计算在div内部/外部花费的时间
我正在学习Rxjs,想自己尝试几个例子 但我似乎不能让我的头去思考 我试图计算用户的鼠标指针在div内外花费的时间 见小提琴-Rxjs-计算在div内部/外部花费的时间,rxjs,Rxjs,我正在学习Rxjs,想自己尝试几个例子 但我似乎不能让我的头去思考 我试图计算用户的鼠标指针在div内外花费的时间 见小提琴- 设$space=$(“.space”) 输入$=Rx.Observable.fromEvent($space,“mouseenter”) .map((事件)=>“in”) 释放$=Rx.Observable.fromEvent($space,“mouseleave”) .map((事件)=>“out”) 让inOut$=Rx.Observable.merge(in$,
设$space=$(“.space”)
输入$=Rx.Observable.fromEvent($space,“mouseenter”)
.map((事件)=>“in”)
释放$=Rx.Observable.fromEvent($space,“mouseleave”)
.map((事件)=>“out”)
让inOut$=Rx.Observable.merge(in$,out$)
让时间$=Rx.可观测间隔(1000)
.buffer(inOut$)
.map((列表)=>list.length)
time$.subscribe((值)=>console.log(值));
我能够计算时间,但如何将其与相应的输入/输出流关联?我希望输出看起来像:
- 内,内-20,外-30
- 外面,进20,出35
- 内,内-100,外-35
另外,有人能给我举一些我可以做的例子,这样我就可以开始在反应范式中思考了吗?当我开始使用Rx时,我发现最具挑战性的事情之一是使用流的流,并适应
flatMap
和switchMap
。您描述的问题正是使用这种方法最容易解决的。您的流定义如下(我更喜欢const
而不是let
,以明确无突变发生):
您可以按以下方式描述进入和离开:
const inThenOut$ = in$.switchMap(() => out$);
为了准确理解这一点,我敦促您了解flatMap
,熟悉流媒体,然后仅通过维护对最新内部流的订阅来了解switchMap
的工作原理。为此,我发现官方rxjs文档是最好的来源。附带的大理石图表通常只通过几个点和线来讲述复杂的故事
从这里开始,花在室内的时间相对来说是一小步。首先,我们将原始流映射为时间戳值:
const timestamp = () => + new Date();
const in$ = Rx.Observable.fromEvent($space, 'mouseenter').map(() => timestamp());
const out$ = Rx.Observable.fromEvent($space, 'mouseleave').map(() => timestamp());
(注意:rxjs中有一个timestamp
方法,您可以使用它来代替手动操作,但我觉得这更好地说明了如何将流元素映射到任何您喜欢的内容中)
从那里,我们可以调整我们的开关映射
用法,以访问输入值和输出值,并返回它们之间的差异:
const inThenOut$ = in$.switchMap(() => out$, (x, y) => y - x);
以下是整个工作流程:
官方文件()中有一些例子,但它们确实有点稀少 我想我会给你一些这样的样品: 这将以$开始侦听,然后在发生
mouseenter
-事件时,它开始侦听mouseleaves
,取其中一个事件并计算持续时间
为了清晰起见,我在每个图下面都写了多个图,但当然你可以把它们组合成一个函数。你可以用一个可观察到的东西来给每个发出的东西贴上时间戳,指示它发出的时间
const { fromEvent } = Rx;
const { map, switchMap, timestamp, take, tap } = RxOperators;
const in$ = fromEvent($space, 'mouseenter').pipe(
timestamp(),
tap(x => console.log(`In: ${x.timestamp}`))
)
const out$ = fromEvent($space, 'mouseleave').pipe(
timestamp(),
tap(x => console.log(`Out: ${x.timestamp}`))
)
const duration$ = in$.pipe(
switchMap(start => out$.pipe(
take(1),
map(finish => finish.timestamp - start.timestamp),
tap(value => console.log(`Duration ms: ${value}`))
)
)
)
/* output example
In: 1552295324302
Out: 1552295325158
Duration ms: 856
*/
请在此处尝试:
const inThenOut$ = in$.switchMap(() => out$, (x, y) => y - x);
let $space = $(".space")
let in$ = Rx.Observable.fromEvent($space, "mouseenter")
let out$ = Rx.Observable.fromEvent($space, "mouseleave")
let durations$ = in$
.map(_ => Date.now())
.switchMap(inTime => out$
.take(1)
.map(_ => Date.now())
.map(outTime => outTime - inTime)
)
durations$
.scan((sum, next) => sum + next, 0)
.subscribe(total => console.log(total))
const { fromEvent } = Rx;
const { map, switchMap, timestamp, take, tap } = RxOperators;
const in$ = fromEvent($space, 'mouseenter').pipe(
timestamp(),
tap(x => console.log(`In: ${x.timestamp}`))
)
const out$ = fromEvent($space, 'mouseleave').pipe(
timestamp(),
tap(x => console.log(`Out: ${x.timestamp}`))
)
const duration$ = in$.pipe(
switchMap(start => out$.pipe(
take(1),
map(finish => finish.timestamp - start.timestamp),
tap(value => console.log(`Duration ms: ${value}`))
)
)
)
/* output example
In: 1552295324302
Out: 1552295325158
Duration ms: 856
*/