You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphQL如何使用useSubscription hook实现延迟读取数据

实现方案

分服务端和客户端两种实现路径,优先推荐服务端实现,可降低无效带宽消耗。

服务端实现(推荐)

核心思路是对MongoDB change stream的事件流做节流,每5秒仅推送一次时间窗口内的最新值,你可以借助RxJS的操作符快速实现:

import { fromEvent } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
import { pubSub } from './你的pubSub实例路径';

const resolvers = {
  Subscription: {
    latestCollectionData: {
      subscribe: () => {
        // 初始化MongoDB change stream
        const changeStream = db.collection('目标集合名').watch([], {
          fullDocument: 'updateLookup'
        });
        // 将change stream事件转为Observable流后做5秒节流
        const throttledStream = fromEvent(changeStream, 'change').pipe(
          // trailing设为true保证取每个时间窗口的最后一条(即最新)数据
          throttleTime(5000, undefined, { leading: false, trailing: true })
        );
        return pubSub.asyncIterator(throttledStream);
      }
    }
  }
};

如果不想引入RxJS,也可以自己实现缓存逻辑:监听到change事件时仅更新缓存的最新值,每5秒检测一次缓存是否有更新,有更新则推送并清空缓存。

客户端实现(适合无法修改服务端的场景)

核心思路是先缓存所有推送来的最新值,每5秒仅更新一次视图状态,示例代码如下:

import { useSubscription, gql } from '@apollo/client';
import { useState, useEffect, useRef } from 'react';

// 你的订阅查询语句
const DATA_SUBSCRIPTION = gql`
  subscription SubscribeCollectionData {
    latestCollectionData {
      id
      value
      createTime
    }
  }
`;

function DataDisplay() {
  // 存储最新的推送数据,不直接触发视图更新
  const latestDataRef = useRef(null);
  // 对外暴露的、用于视图渲染的数据
  const [displayData, setDisplayData] = useState(null);
  const { data } = useSubscription(DATA_SUBSCRIPTION);

  // 收到订阅推送时更新缓存
  useEffect(() => {
    if (data?.latestCollectionData) {
      latestDataRef.current = data.latestCollectionData;
    }
  }, [data]);

  // 每5秒读取一次缓存的最新值更新视图
  useEffect(() => {
    const intervalTimer = setInterval(() => {
      if (latestDataRef.current) {
        setDisplayData(latestDataRef.current);
      }
    }, 5000);
    // 组件卸载时清除定时器
    return () => clearInterval(intervalTimer);
  }, []);

  return <div>当前最新值:{displayData?.value ?? '无数据'}</div>;
}

注意事项

  • 高写入量场景下,还可以直接在服务端跳过change stream监听,改为每5秒直接查询MongoDB集合的最新数据推送,进一步降低服务端监听开销
  • 两种方案均可以灵活调整时间窗口长度,把示例中的5000毫秒替换为你需要的数值即可

内容的提问来源于stack exchange,提问作者ATHER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:15:00