gpt4 book ai didi

javascript - 如何有条件地分支 rxjs 流?

转载 作者:行者123 更新时间:2023-12-01 15:28:09 32 4
gpt4 key购买 nike

我正在尝试模拟任何图像编辑器中的“画笔”功能。

我有以下流:

  • $pointerDown : 指针按下
  • $pointerUp : 指针按下
  • $position : 画笔位置
  • $escape : 按下退出键

  • 我想做的事

    当用户拖动鼠标时,做临时计算。如果鼠标已启动,则提交这些更改。如果按下了转义键,则不要提交这些更改。

    我目前正在处理的是第一种情况:
    $pointerDown.pipe(
    r.switchMap(() =>
    $position.pipe(
    r.throttleTime(150),
    r.map(getNodesUnderBrush),
    r.tap(prepareChanges),
    r.takeUntil($pointerUp),
    r.finalize(commitBrushStroke))
    )).subscribe()

    如何以两种不同的方式结束流?什么是惯用的 rxjs?

    谢谢

    最佳答案

    关于您的问题,我可以看到您需要某种 state随着时间的推移。在这里你的statepointerdown/move/dragging可观察的,必须是 accumulatedcleared最后是 emitted .当我看到这样的state场景我总是喜欢使用scan运算符(operator):

    上一页

    为了简单的示例,我没有使用您预定义的 observables。如果您在将特定指针用例调整为非常相似的用例时遇到问题,我可以尝试对其进行更新,使其更接近您的问题

    1. 什么可以代表我的状态

    在这里,我使用枚举 [status] 稍后对之前发生的事件使用react,并使用累积 [acc] 随着时间推移的点

    interface State {
    acc: number[],
    status: Status
    }

    enum Status {
    init,
    move,
    finish,
    escape
    }

    const DEFAULT_STATE: State = {
    acc: [],
    status: Status.init
    }

    2. 编写改变状态的函数

    你的需求可以拆分成:accumulate [pointerdown$ + position$],finish [pointerup$],escape [escape$]
    const accumulate = (index: number) => (state: State): State =>
    ({status: Status.move, acc: [...state.acc, index]});

    const finish = () => (state: State): State =>
    ({status: Status.finish, acc: state.acc})

    const escape = () => (state: State): State =>
    ({status: Status.escape, acc: []})

    3. 将你的函数映射到你的 observable
    merge(
    move$.pipe(map(accumulate)),
    finish$.pipe(map(finish)),
    escape$.pipe(map(escape))
    )

    4. 使用扫描中放置您的状态随时间变化的函数
    scan((acc: State, fn: (state: State) => State) => fn(acc), DEFAULT_STATE)

    5. 处理你的变异状态

    这里我们只想处理如果我们有一个完成,所以我们过滤它
    filter(state => state.status === Status.finish),

    内态样本
  • move$.next('1') = State: {status: move, acc: ['1']}
  • escape$.next() = State: {status: escape, acc: []}
  • move$.next('2') = State: {status: move, acc: ['2']}
  • finish$.next() = 状态:{状态:完成,acc:['2']}

  • 正在运行 stackblitz

    仅供引用:很难获得这种用 rxjs 解决状态问题的心态。但是一旦你理解了这个想法背后的流程,你就可以在几乎所有有状态的场景中使用它。您将避免副作用,坚持 rxjs 工作流程,并且可以轻松优化/调试您的代码。

    关于javascript - 如何有条件地分支 rxjs 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60719716/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com