【问题标题】:Keep hitting API without setInterval在没有 setInterval 的情况下继续访问 API
【发布时间】:2022-01-18 07:40:15
【问题描述】:

我有三页。主页、聊天页面和带有聊天图标的顶部导航页面。当用户收到新消息时,我想在顶部导航中显示带有聊天图标的徽章。为此,我在聊天模型中维护了一个名为 see 的标志。这是一个布尔值。如果看到的是 false,我会统计为 false 的记录,并在带有聊天图标的徽章中显示计数。为此,我在顶部导航 ngOnit() 中编写了一个方法来检查聊天模型是否有任何看不见的消息。我觉得它会影响性能,因为如果每隔一秒点击一次 API。有没有比 setInterval 更好的方法。

顶部导航 TS

ngOnInit()
        {
            setInterval(() => {
               //API Call
                }, 1000);
        }

【问题讨论】:

  • 你可以创建一个 websocket 连接,这几乎就是创建它的确切用例,尽管你的服务器环境可能不支持它
  • 除了 websockets 之外你还可以做的另一件事是使用指数退避来检查 API 以降低频率。例如,从每 1 秒检查一次开始,然后在 10 次迭代后,将轮询时间增加到 2 秒,然后是 4、8 等等,直到合理的最大值。如果输入/发送/接收新消息,请将间隔重置为 1 秒。这样一来,轮询在一系列谈话期间基本上是实时的,但在空闲期间略有延迟en.m.wikipedia.org/wiki/Exponential_backoff
  • 你能给我一些关于如何用 websocket 做的参考吗?
  • 您也可以考虑将服务器发送事件作为 Web Sockets 的替代方案。

标签: javascript angular typescript rest


【解决方案1】:

您应该考虑设置websocket 服务器,而不是连续访问 API。您可以从Angular 应用程序连接到您的服务器到emitlisten 实时获取消息。


服务器(NodeJs 上的 websocket)

这是一个简单的websocket 服务器在NodeJs 中的样子:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8081 });
  
wss.on('connection', ws => {
  onConnection(ws);
  ws.on('message', message => {
    onMessage(message, ws);
  });
  ws.on('error', error => {
    OnError(error);
  });
   ws.on('close', ws=> {
    onClose();
})
});

客户端(角度)

在您的 Angular 应用程序中,这是处理此连接的客户端服务的样子。本质上,您创建一个连接到您的服务器的服务,处理emitsubscriptions - 将新消息发送到Subject。您可以将此Subject 作为Observable 返回,然后在您的组件中订阅它。

import { Injectable } from '@angular/core';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { environment } from '../../environments/environment';
import { catchError, tap, switchAll } from 'rxjs/operators';
import { EMPTY, Subject } from 'rxjs';
export const WS_ENDPOINT = environment.wsEndpoint;
  
@Injectable({
  providedIn: 'root'
})
export class DataService {
  private socket$: WebSocketSubject<any>;
  private messagesSubject$ = new Subject();
  public messages$ = this.messagesSubject$.pipe(switchAll(), catchError(e => { throw e }));
  
  public connect(): void {
  
    if (!this.socket$ || this.socket$.closed) {
      this.socket$ = this.getNewWebSocket();
      const messages = this.socket$.pipe(
        tap({
          error: error => console.log(error),
        }), catchError(_ => EMPTY));
      this.messagesSubject$.next(messages);
    }
  }
  
  private getNewWebSocket() {
    return webSocket(WS_ENDPOINT);
  }
  sendMessage(msg: any) {
    this.socket$.next(msg);
  }
  close() {
    this.socket$.complete(); }}

看看这篇文章,它描述了websocket 服务器的工作原理以及来自Angular 应用程序的连接:https://javascript-conference.com/blog/real-time-in-angular-a-journey-into-websocket-and-rxjs/

【讨论】:

    猜你喜欢
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 2012-07-07
    • 2011-01-14
    相关资源
    最近更新 更多