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$,

我正在学习Rxjs,想自己尝试几个例子 但我似乎不能让我的头去思考

我试图计算用户的鼠标指针在div内外花费的时间

见小提琴-


设$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
*/