简体   繁体   English

如何在 Rx.js 中对不完整序列计算 Observable

[英]How to count Observable on incomplete sequence in Rx.js

I have an obeservable sequence, where each time a call realease event occurs I map that event to an http request that returns some call logs that I then filter and need to get a count form.我有一个可观察的序列,每次发生调用 realease 事件时,我都会将该事件映射到一个 http 请求,该请求返回一些调用日志,然后我对其进行过滤并需要获取计数表单。 The problem is that even though the mapped obserbable that returns the json from the http request and the sequence has completed the orginal fromEvent Observable has not terminated so count will not emit anything.问题是,即使映射的 obserbable 从 http 请求返回 json 并且序列已经完成,原始的 fromEvent Observable 还没有终止,所以 count 不会发出任何东西。 I need a count of the filtered amount each time the http request comes back not sure how to do this.每次 http 请求返回时,我都需要对过滤量进行计数,但不确定如何执行此操作。

var seq = Rx.Observable
        .fromEvent(call realease event)
        .flatMap(agentObj => 
          Rx.Observable.fromPromise(callLogHelper.getUserCallLogs(agentObj.agentId))
        )
        .flatMap(logs => Rx.Observable.fromArray(logs))
        .filter(log => log.callTime >= 210)
        .count();

I tried a few methods that very helpful people offered including user3743222 , which i am very thankful for.我尝试了一些非常有帮助的人提供的方法,包括 user3743222 ,我非常感谢。 These included scan, sample, expand and using the idx argument in map and filter.这些包括扫描、采样、扩展和在映射和过滤器中使用 idx 参数。 The main issue i keep getting is that these methods return a continuous running total and because the http request can have duplicate data from the last time it was called the running count needs to be reset each time the http request is returned.我一直遇到的主要问题是这些方法返回一个连续的运行总数,并且因为 http 请求可能有上次调用它的重复数据,所以每次返回 http 请求时都需要重置运行计数。

I ended up just mapping the filtered values from the request in the flatMap as simple array operations and then just returning the length.我最终只是将 flatMap 中请求的过滤值映射为简单的数组操作,然后只返回长度。 I feel like this is a hacky solution tho我觉得这是一个hacky解决方案

var seq = Rx.Observable
        .fromEvent(call realease event)
        .flatMap(agentObj => 
             Rx.Observable.fromPromise(callLogHelper.getUserCallLogs(agentObj.agentId))
        )
        .flatMap((logs) => {
             var filteredLogs = logs.filter(log => log.callTime >= 210);
             return  Rx.Observable.of(filteredLogs.length);
         })

Based on the solution you came up with it would seem simpler to just do:根据您提出的解决方案,这样做似乎更简单:

var seq = Rx.Observable
        .fromEvent(call realease event)
        .flatMap(
          agentObj => callLogHelper.getUserCallLogs(agentObj.agentId),
          (ao, logs) => logs.filter(log => log.callTime >= 210).length
        );

One way to do this is to use the scan operator.一种方法是使用scan运算符。 In practice, it would be something like :在实践中,它会是这样的:

var seq = Rx.Observable
        .fromEvent(call realease event)
        .flatMap(flatMap(agentObj => 
          Rx.Observable.fromPromise(callLogHelper.getUserCallLogs(agentObj.agentId))
        ))
        .flatMap(logs => Rx.Observable.fromArray(logs))
        .filter(log => log.callTime >= 210)
        .scan (function (count, _){return ++count},0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM