【问题标题】:Reactive pattern for combing operator where one is dependent on another一个依赖于另一个的组合运算符的反应模式
【发布时间】:2016-12-19 04:55:56
【问题描述】:

我有一个使用 REST 服务的应用程序。每次有人发出请求时,例如单击一个按钮。但是,它需要先获取令牌,然后每 20 分钟刷新一次。这是一个大理石图,表示所需的流组合...

TOKEN SOURCE   ---------A--------------B--------------C----------------D-
REQUEST SOURCE ----1-----------2--3---------4-----------5-------6--------


RESULT SOURCE  ---------A1-----A2-A3--------B4----------C5------C6-------

通常,请求源会触发与令牌源的最新值相结合的结果,但是当令牌流上没有发出任何项目时会出现异常 - 在这种情况下,请求会被缓冲,直到第一个令牌到达并且然后发送。

combineLatest 运算符几乎就在那里,但它会在任一流发出时触发。 sample 运算符的弹珠图看起来也很接近,但它会根据我不想要的时间间隔限制输出。

哪个运算符/运算符链适用于此实例?

我正在使用 RxJS 进行原型设计,但我需要在 RxSwift 中实现。

【问题讨论】:

    标签: operators rxjs reactive-programming rx-swift


    【解决方案1】:

    您已接近解决方案。重要的细节是 Source (2) 投影了它的所有元素,而 Source (1) 不直接投影,当只有 Source (1) 发生变化时,拥有额外的信息可以帮助我们丢弃。

    s1.combineLatest(s2, (a, b) => [a, b])
      .distinctUntilChanged(v => v[1])
    

    这是测试设置:

    var s1 = Rx.Observable.interval(997).take(10).map(i => String.fromCharCode(65 + i))
    var s2 = Rx.Observable.interval(251).take(10).delay(500).skip(1)
    
    s1.combineLatest(s2, (a, b) => [a, b])
      .distinctUntilChanged(v => v[1])
      .subscribe(value => console.log(value))
    

    输出:

    ["A",1] [“A2] [“A”,3] ["A",4] ["B",5] ["B",6] [“B”,7] [“B”,8] ["C",9]

    【讨论】:

    • interval 的魔法值是素数,所以保证两个序列不重叠。
    【解决方案2】:

    由于您希望仅根据您的 REQUEST SOURCE 触发数据发射,因此这可能是以此开始您的流然后切换 - 或者在本例中为 flatMap - 到 @ 987654324@ 并结合这两个 - 不需要高级运算符:

    (注意:我的假设是,您的 TOKEN SOURCE 确实重放了最新的令牌:

    var token$ = Rx.Observable.interval(1000).take(10).map(() => Math.random()).publishReplay(1); // simulating the token source: new token every second and replaying the latest token
    var requests$ = Rx.Observable.interval(250).take(10); // simulating the request source: emitting a new request every 250ms
    token$.connect();
    
    requests$
        .flatMap(request => token$
            .take(1)
            .map(token => ({request, token}))
        )
        .subscribe(function(requestWithToken) {
            console.log("Matched: ", requestWithToken);
        });
    

    你可以在这里查看现场小提琴:https://jsfiddle.net/rn8rzufg/

    【讨论】:

    • 谢谢!当我在使用 RxJS 时将 publishReplay 更改为 replay 时,这有效...
    猜你喜欢
    • 1970-01-01
    • 2017-02-19
    • 2019-08-23
    • 1970-01-01
    • 2016-08-25
    • 2016-07-18
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多