如何在 NestJS 中使用服务器推送实现持续返回进度数据

1,158 阅读1分钟

当我们需要处理较长时间的接口请求时,我们通常需要一种能够告知用户当前处理进度的方式,这样用户就可以清楚地知道系统正在做些什么。而服务器推送(Server-Sent Events)就是一种能够满足这种需求的技术,它可以让服务器在接收到数据时立即向客户端推送数据,从而不必等待客户端请求数据。

在 NestJS 中,我们可以使用 @nestjs/common 中的 @Get() 装饰器创建路由,并使用 @Sse() 装饰器指定服务器推送的路由。例如,我们可以创建一个名为 /progress 的服务器推送路由,如下所示:

import { Controller, Get, EventSource } from '@nestjs/common';

@Controller()
export class AppController {
  @Sse('progress')
  async progress() {
    const events = [
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
    ];
    for (const event of events) {
      yield { data: event };
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
}

在这个示例中,我们使用一个循环来模拟进度,并使用 yield 语句来返回进度数据。同时,我们使用 await new Promise(resolve => setTimeout(resolve, 1000)) 来暂停 1 秒钟,以便模拟处理进度。

接下来,我们需要在客户端应用程序中订阅服务器推送。我们可以使用 EventSource 对象来订阅服务器推送,并使用 eventSource.onmessage 事件处理程序来处理接收到的消息。例如,我们可以创建以下代码来订阅名为 /progress 的服务器推送:

const eventSource = new EventSource('/progress');
eventSource.onmessage = event => console.log(event.data);

在这个示例中,我们使用 EventSource 对象来订阅名为 /progress 的服务器推送。我们使用 eventSource.onmessage 事件处理程序来处理接收到的消息。当接收到一条消息时,我们将其输出到控制台。