V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
weishijun14
V2EX  ›  JavaScript

请教一个 rxjs 问题。。。。。。

  •  
  •   weishijun14 · 2020-02-14 23:53:34 +08:00 · 3857 次点击
    这是一个创建于 1748 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个需求,

    1. 我点击按钮,
    2. 获得数组,长度为 100
    3. 我会使用其中三个
    4. 当我再次点击按钮的时候,我希望不用重新获得,因为还有 97 个未用完。直接 97 - 3 即可。
    5. 直到 100 个全部用完,才再次发送请求获取下一个 100 个数据。

    求教,,, 或者说一下关键的思路,, 我是 rxjs 新手,百思不解了。。

    23 条回复    2020-02-17 21:22:18 +08:00
    xcstream
        1
    xcstream  
       2020-02-15 00:28:37 +08:00
    思考了一下 好像不需要 rxjs 也很好写
    weishijun14
        2
    weishijun14  
    OP
       2020-02-15 00:41:27 +08:00
    @xcstream 我在学 rxjs 这是我找的一个练习。。
    sivacohan
        3
    sivacohan  
       2020-02-15 01:00:12 +08:00 via iPhone
    我没用过 rxjs,你这个需求就是要实现个 queue。
    每次远程取到的数据先入 queue,然后再从 queue 里面取数据到本地。
    godoway
        4
    godoway  
       2020-02-15 02:15:10 +08:00
    应该是背压?
    在 rxjava 里面叫 Flowable,rxjs 里面好像没见有
    shadeofgod
        5
    shadeofgod  
       2020-02-15 03:47:26 +08:00
    写了个类似的逻辑,数组长度是 3,每次消耗 1 个,消耗完了才重新请求。

    https://codesandbox.io/s/4xk3kkok09?expanddevtools=1&fontsize=14&hidenavigation=1&theme=dark
    shadeofgod
        6
    shadeofgod  
       2020-02-15 03:59:04 +08:00
    但感觉不太对,我也是很少用 rx
    Perry
        7
    Perry  
       2020-02-15 05:15:12 +08:00 via iPhone
    可能需要另外一条线 track 需不需要再请求
    cuzfinal
        8
    cuzfinal  
       2020-02-15 09:02:06 +08:00 via Android
    你为什么不看看文档呢
    meteor957
        9
    meteor957  
       2020-02-15 09:35:52 +08:00
    @cuzfinal 你又知道人家没看过文档?
    wly19960911
        10
    wly19960911  
       2020-02-15 10:44:36 +08:00
    datasource 的队列别拿 rxjs 做,这个是舍近求远的行为。只需要做个 queue 然后调用方法获取到队列前三位就行了。

    直接 fromEvent(window, 'click').pipe(
    switchMap(v => fromPromise(datasource.get(3))),
    ).subscribe(() => {});
    GiantHard
        11
    GiantHard  
       2020-02-15 12:08:21 +08:00   ❤️ 1
    Rx 是用来“推”数据的,而你的需求是“拉”数据,这就可以用到 IxJS: https://codesandbox.io/s/rx-ix-t21qn
    lijsh
        12
    lijsh  
       2020-02-15 12:19:06 +08:00
    momocraft
        13
    momocraft  
       2020-02-15 12:22:49 +08:00
    什么叫"使用" "获得"?
    weishijun14
        14
    weishijun14  
    OP
       2020-02-15 12:31:47 +08:00
    @lijsh 我就是看了这篇,但是我做的东西和他又稍有不同。。。我增加了一些新特性。。
    weishijun14
        15
    weishijun14  
    OP
       2020-02-15 12:33:43 +08:00
    @wly19960911 你的意思是前端只管取就好了。。100 -3 的行为交给后端么。。
    weishijun14
        16
    weishijun14  
    OP
       2020-02-15 12:34:42 +08:00
    @momocraft 使用就是 view 层只需要显示 3 个。 获得就是发请求。
    weishijun14
        17
    weishijun14  
    OP
       2020-02-15 12:36:50 +08:00
    @GiantHard 大佬又引入一个库啊。。。
    @cuzfinal 文档也在看。。但是就是没有头绪。。

    anyway 谢谢🙏楼上各位大佬解答。。
    weishijun14
        18
    weishijun14  
    OP
       2020-02-15 12:38:19 +08:00
    @shadeofgod 我研究下你这个代码。。
    yoyooyooo
        19
    yoyooyooo  
       2020-02-15 15:08:10 +08:00
    只是缓存个数组的话也没必要用 rxjs,强行用的话另外搞个 BehaviorSubject 存起来好了,不是 rxjs 熟练工,简单实现:

    const data$ = new BehaviorSubject([]);

    fromEvent(document, "click")
    .pipe(
    withLatestFrom(data$),
    switchMap(([e, data]) => {
    return data.length < 3
    ? from(defer(() => mockFetch())).pipe(tap(v => data$.next(v)))
    : of(data);
    }),
    tap(data => data$.next(data.slice(0, data.length - 3))),
    tap(data => {
    console.log(data);
    })
    )
    .subscribe();
    mxT52CRuqR6o5
        20
    mxT52CRuqR6o5  
       2020-02-15 15:37:27 +08:00
    根据前面的评论学习了一下,这应该是背压问题,google 了一下有官方指导
    http://reactivex.io/documentation/operators/backpressure.html
    关键应该是在 ControlledObservable 上
    wly19960911
        21
    wly19960911  
       2020-02-16 08:53:11 +08:00
    @weishijun14 datasource 不是指后端,单纯就是一个获取数据的库,至于背压问题我看了下,rxjs 不太好做这种重复,因为 rxjs 一开始就准备好了数据观测,除非有人手动触发了获取数据的操作。

    switchMap 的 observable 也需要有 subject 来推数据进去。所以这个行为比较难以实现,不如写个库专门拿队列数据。由 rxjs 取就行了。如果不是需要重新拉取这个操作,我感觉挺好实现的...
    StrayBugs
        22
    StrayBugs  
       2020-02-16 15:38:04 +08:00
    大家这么快给实现,然而楼主的描述不是很完整。当请求 pending 时如果按下了按键怎么算?忽略还是算多次取?多次请求返回的结果怎么处理?抛弃旧的还是一并连起来?
    shadeofgod
        23
    shadeofgod  
       2020-02-17 21:22:18 +08:00
    @StrayBugs 你说的对,先定义清楚需求是更好的方式,不过对于闲逛论坛的人来说碰到每一个问题都像面试一样面对的话太累了。所以只是随手一写抛个思路
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5401 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:56 · PVG 15:56 · LAX 23:56 · JFK 02:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.