当前位置: 首页 > 知识库问答 >
问题:

RXJS:限制时间加上最后一个值

齐成和
2023-03-14

我有一个场景,其中许多事件可以在短时间内发送到流。我想要一个操作符,它是debounceTimethrottleTime的混合体。

下面的演示可以用来说明我想要什么,https://stackblitz.com/edit/rxjs6-demo-jxbght?file=index.ts.我希望订阅服务器获取第一个发出的事件,然后等待x毫秒。如果在等待时间内发出更多事件,则应在等待时间后将最后一个事件发送给订阅服务器。等待时间应该在每个新发出的事件上重置,就像去盎司一样。

如果在1秒内单击按钮3次,则应打印1和3。如果在1秒内仅单击1次,则应仅打印4次。如果再次单击3次,则应打印5和7。

这不适用于debounceTime,因为它不会给我第一个事件,也不适用于throttleTime,因为它不会给我等待时间结束后最后发出的值。

有没有关于如何实施的建议?

更新

在Martins回答的帮助下,我创建了一个自定义运算符。不确定它是否100%正确工作,或者是否有更好的方法来做,但它似乎做了我想要的。

import { Observable, empty } from 'rxjs';
import { exhaustMap, timeoutWith, debounceTime, take, startWith } from 'rxjs/operators';

export function takeFirstThenDebounceTime(waitTime) {
    return function takeFirstThenDebounceTimeImplementation(source) {
        return Observable.create(subscriber => {
            const subscription = source.
                pipe(
                    exhaustMap(val => source.pipe(
                        timeoutWith(waitTime, empty()),
                        debounceTime(waitTime),
                        take(1),
                        startWith(val)
                    )),
                )
                .subscribe(value => {
                    subscriber.next(value);
                },
                    err => subscriber.error(err),
                    () => subscriber.complete());

            return subscription;
        });
    }
}

共有2个答案

宰烈
2023-03-14

此运算符应该为您提供第一个值、受限制的流和最后一个值:

js prettyprint-override">export function throunceTime<T>(duration: number): MonoTypeOperatorFunction<T> {
  return (source: Observable<T>) =>
    merge(source.pipe(throttleTime(duration)), source.pipe(debounceTime(duration)))
      .pipe(throttleTime(0, undefined, { leading: true, trailing: false }));
}
宇文修文
2023-03-14

在RxJS 6中,有一些额外的选项用于限制时间运算符,这些运算符现在没有文档化,您可以在持续时间的开始和结束时使其发出。所以也许这能帮到你。

https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttleTime.ts#L55

https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttle.ts#L12

但是,由于要在每次发射时重置超时,因此会更加复杂。这应该是随机发射的简化示例,但我想知道是否有更简单的方法

const shared = source.pipe(shareReplay(1))

shared
  .pipe(
    exhaustMap(val => shared.pipe(
      timeout(1000),
      catchError(() => empty()),
      debounceTime(1000),
      take(1),
      startWith(val),
    ))
  )
  .subscribe(v => console.log(v))

此演示在175ms间隙后衰减。我希望这对你有意义。

演示:https://stackblitz.com/edit/rxjs6-demo-ztppwy?file=index.ts

 类似资料:
  • 我试图在我的应用程序中限制不必要的HTTP调用的数量,但是每次我订阅一个可观察的请求都会向服务器发出请求。有没有一种方法可以订阅可观察的,而不会触发超文本传输协议请求?我的可观察服务看起来是这样的: 然后在我的组件中,我同意如下所示的可观察性:

  • 问题内容: 我有一个包含3个字段的表格: 在SQL语言中,尤其是Postgres,有没有一种方法可以选择last的值而不必这样做? 普通查询: 我有兴趣避免这种限制,因为我需要将它作为子查询。 问题答案: 如果您的id列是一个自动递增的主键字段,则非常简单。假定最新笔记具有最高ID。(那可能不是真的;只有您知道!) 它在这里:http : //sqlfiddle.com/#!2/7478a/1/0

  • 给定一个字符串,在不重复字符的情况下,找到最长子字符串的长度。例如,“abcabcbb”的不重复字母的最长子字符串是“abc”,其长度为3。对于“bbbbb”,最长的子字符串是“b”,长度为1。 对于长可重复字符串的最后一次测试,超过了时间限制。不知道如何优化。寻求改进,谢谢

  • HttpSession 接口的 getLastAccessedTime 方法允许 servlet 确定在当前请求之前的会话的最后访问时间。当会话中的请求是 servlet 容器第一个处理时该会话被认为是访问了。

  • 我有这个正则表达式: 这为我提供了许多我所需要的结果。但是,我无法检查一个条件: 我不希望我的最后一个字符是“-”。它可以出现在第二个“/”之后的任何位置,而不是最后一个字符。更准确地说,最后一个字符应该是任何,而不是连字符“-”。 我查看了这个,但是我无法理解它。这到底是怎么做到的。

  • 问题内容: 假设我有一个代码,要求用户提供一些输入,例如: 但是我想给用户60秒的时间限制,然后抛出一个异常(在这种情况下,我认为是)。我怎么做? 问题答案: