【问题标题】:RxJS which operator to use for "onIdle"?RxJS 哪个运算符用于“onIdle”?
【发布时间】:2021-01-02 03:17:58
【问题描述】:

我的用例如下 - 我有一个针对不同元素的操作流,我只想在每个对象空闲一段时间或收到不同元素时才对每个对象调用“提交”。

我正在尝试使用 groupBy 和 debounce,但没有涵盖所有案例 - 例如

action.pipe(
  groupBy(item -> item.key),
  debounceTime(1000),
  mergeMap(item -> { 
           item.commit()})
)

【问题讨论】:

  • “空闲”是什么意思?如何检查对象是否处于空闲状态?
  • 空闲,如“未收到 X 毫秒的事件”
  • 我不确定我是否理解正确。因此,如果在 X 毫秒内没有发出具有相同键的其他项目,或者如果发出具有不同键的另一个项目,您想在 action 发出的项目上调用 commit?!
  • 如果具有不同键的元素到达或在给定时间内没有事件到达,我想在最后收到的元素上调用提交。 A => A => B => A 应该导致: A.commit() => B.commit() => => A.commit()

标签: rxjs reactive redux-observable


【解决方案1】:

我不确定你的目标是什么:

让我们以 A => B => A 小于最短空闲时间的情况为例

选项 1:每种类型的元素都应有各自的空闲状态 - 类型 A 的第二次发射将被忽略
选项 2。由于没有连续的序列,第二个A 不会被忽略

选项 1 示例:

action.pipe(
    groupBy(item => item.key),
    mergeMap(group => group.pipe(debounceTime(1000))),
    mergeMap(item => item.commit())
)

可选:

const IDLE_TIME = XXXX;
action.pipe(
    groupBy(item => item.key),
    mergeMap(group => merge(
        group.pipe(first()),
        group.pipe(
            timeInterval(),
            filter(x => x.interval > IDLE_TIME),
            map(x => x.value)
        )
    )),
    mergeMap(item => item.commit())
)

选项 2 示例:

 action.pipe(
     pairwise(),
     debounce(([previous, current]) => previous.key == current.key? timer(1000) : EMPTY),
     map(([pre, current]) => current),
     mergeMap(item => item.commit())
 )

【讨论】:

    【解决方案2】:

    您可以使用auditTimescanfilter 评估空闲性质

    action.pipe(
      //add the idle property to the item
      map(item => ({ ...item, idle: false})),
      //audit the stream each second
      auditTime(1000),
      //then use scan to with previous emission at audit time
      scan(
         (prev, curr) => {
           //then if the key remains the same then we have an idle state
           if (prev.key === curr.key) {
              //return changed object to indicate we have an idle state
              return Object.assign({}, curr, {idle: true});
           } else {
              //otherwise just return the non idle item
              return curr 
           }
        //seed with an object that cannot match the first emission key
        }, { key: null }
      ),
      //then filter out all emissions indicated as not idle
      filter(item => item.idle === true)
      //and commit
      mergeMap(item => item.commit())
    )
    

    那么你可以使用distinctUntilKeyChanged 来实现第二个条件

    action.pipe(
      distinctUntilKeyChanged('key'),
      mergeMap(item => item.commit())
    )
    

    我不熟悉redux-observable,但您通常会merge 这两个可观察对象,然后在最后提交。

    【讨论】:

    • 我不确定在这里使用auditTime 是否明智
    • 好的。如果您提供理由,可能最适合任何读者?
    • 还要考虑一下你有 3 个元素来自 A --> B --> A 的情况,你的代码只知道前一个。
    • distinctUntilKeyChanged 排放也不例外。
    • distinctUntilKeyChanged 在上述情况下如何帮助您?
    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 2018-05-13
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 2017-04-28
    • 2020-11-16
    相关资源
    最近更新 更多