使用useSubscription时丢失部分新数据的问题求助
Apollo订阅接收数据不全的排查与解决
问题场景
使用Apollo useSubscription 订阅订单更新时,Apollo Studio显示每次mutation后有5条新数据推送,但客户端通过useEffect打印的liveOrderData仅能收到3条,存在数据丢失情况。
核心原因分析
当前代码中,onData每次直接用新接收的数据覆盖liveOrderData,如果多条订阅消息快速抵达,React的异步状态更新机制可能导致中间消息被覆盖;或者订阅配置、服务端推送逻辑存在异常,导致部分消息未被客户端正常接收。
解决方案
1. 改用函数式状态更新,避免数据覆盖丢失
如果订阅推送的是单条更新数据,需要将新数据累加进状态(而非直接覆盖),确保每条消息都被保留:
const [liveOrderData, setLiveOrderData] = useState([]) // 初始化为空数组 useSubscription(traderSubscriptions.FIND_LIVE_ORDER_UPDATES, { variables: { ...myVariables }, onData: (res) => { const newOrderUpdate = res.data.data.findLiveOrderUpdates; // 函数式更新,基于最新状态追加新数据 setLiveOrderData(prevData => [...prevData, newOrderUpdate]); }, onError: (error) => { console.error('订阅错误:', error); // 捕获可能的消息接收错误 } })
如果订阅推送的是全量数据快照,则需要确认服务端是否每次都返回完整的5条数据,若服务端推送的快照本身缺失,需排查服务端resolver逻辑。
2. 检查Apollo客户端订阅配置
确认Apollo Client的配置中是否存在订阅相关的节流、缓存或批量处理设置,导致部分消息被合并丢弃。比如检查defaultOptions中的订阅配置:
const client = new ApolloClient({ // ...其他配置 defaultOptions: { watchQuery: { /* ... */ }, query: { /* ... */ }, mutate: { /* ... */ }, subscribe: { // 避免设置可能导致消息丢失的选项,如谨慎使用fetchPolicy: 'cache-and-network' } } });
3. 排查服务端推送逻辑
虽然Apollo Studio显示有5条数据,但需确认服务端的订阅resolver是否正确将所有消息推送给客户端:
- 检查resolver中是否有重复数据过滤、错误捕获遗漏的情况,导致部分消息未被
publish - 确认服务端的订阅触发器是否在mutation后正确触发了5次推送
4. 排查React严格模式影响(开发环境)
在React开发环境的严格模式下,组件会被重复渲染,可能导致订阅被取消后重连,丢失部分中间消息。可临时关闭严格模式测试,若数据恢复正常,需调整订阅逻辑确保重连后能同步遗漏数据。
内容的提问来源于stack exchange,提问作者Amir Pasha Bagheri
相关产品推荐
相关产品推荐

