angular - "User is Typing"精益 RXJS 实现

标签 angular typescript rxjs6

我目前正在致力于为多用户聊天室实现“用户正在打字”功能。由于我对 RXJS 的了解有限,我能够生成以下代码片段,它满足“用户正在键入”功能的最低要求:

   this.messageForm.message.valueChanges
      .pipe(
        tap(() => this.convoService.isUserTyping(true)),
        debounceTime(500),
        map(() => this.convoService.isUserTyping(false))
      )
      .subscribe();

但是,这种实现并不理想,因为它向服务器产生了太多请求。我的目标是将请求限制为 2,并使用 RXJS 运算符创建以下行为:

  1. 仅在第一次按键时发出请求
  2. 忽略所有后续按键
  3. 在最后一次按键后等待 X 时间
  4. 如果在倒计时到期之前引入新的按键,则重置倒计时
  5. 倒计时结束后发出请求

最佳答案

这是一种无副作用的实现方法:

const typing$ = this.messageForm.message.valueChanges.pipe(
  switchMap(() => concat(
    of(true),
    of(false).pipe(delay(500)),
  )),
  distinctUntilChanged(),
)

您可以使用它来执行您的请求。如果 isUserTyping 是一劳永逸的,你可以这样做

typing$.subscribe(typing => this.convoService.isUserTyping(typing));

如果它是一个异步请求(并返回一个可观察的),我宁愿这样做:

typing$.pipe(
  concatMap(typing => this.convoService.isUserTyping(typing))
).subscribe();

这样您就可以确保按顺序执行所有请求,避免高延迟情况下出现乱序问题。


如果延迟是一个实际问题,则需要使用缓冲进行更多工作,以避免对请求产生过多的背压,但这超出了该问题的范围。

关于angular - "User is Typing"精益 RXJS 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63970730/

相关文章:

javascript - TypeScript 中有没有办法警告 "1"+ 1 = "11"?

angular - 如何修复 Typescript 可订阅接口(interface)错误?

javascript - 如何触发 rxjs observable

javascript - 将 NodeJs 导入 TypeScript 编译错误

angular - combineLatest 是否因为 behaviorSubject 而没有触发?

javascript - 了解为什么这个导入变量的字符串插值在我的 Angular 2 应用程序中起作用

javascript - 如何将 Angular 4 与现有 Express 项目结合使用

node.js - 获取 http ://localhost: postman

javascript - Angular 2 - 如何向模板发送异步信息

javascript - 类扩展 Uint8Array,如何返回 Uint8Array?