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

如何手动触发Apollo Client Subscription?执行时遇报错求助

解决Apollo GraphQL手动订阅触发的问题

常见报错原因及修正方案

  1. WebSocket链接配置缺失
    确保你的Apollo Client实例已正确配置split链接,区分HTTP请求与WebSocket订阅请求,示例配置如下:
import { split, HttpLink, ApolloClient, InMemoryCache } from '@apollo/client';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { getMainDefinition } from '@apollo/client/utilities';
import { createClient } from 'graphql-ws';

// HTTP链接配置
const httpLink = new HttpLink({
  uri: '你的HTTP接口地址',
});

// WebSocket链接配置
const wsLink = new GraphQLWsLink(createClient({
  url: '你的WebSocket服务地址',
}));

// 按操作类型拆分链接
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink,
);

// 初始化APIClient
const APIClient = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache(),
});
  1. 手动订阅的正确写法(含错误处理与资源清理)
    直接调用APIClient.subscribe时,需处理错误逻辑,并在组件卸载或无需订阅时取消订阅,避免内存泄漏。修改你的代码如下:
// 保存订阅实例,用于后续取消操作
let subscriptionInstance;

// 按钮点击触发订阅的函数
const triggerSubscription = () => {
  // 若已有订阅,先取消避免重复订阅
  if (subscriptionInstance) {
    subscriptionInstance.unsubscribe();
  }

  // 执行手动订阅
  subscriptionInstance = APIClient.subscribe({
    query: BULK_CREATE_PROCESS_DETAILS,
    variables: {
      id: {
        userId: id,
      },
    },
  }).subscribe({
    next: (data) => {
      console.log('订阅返回数据:', data);
    },
    error: (err) => {
      console.error('订阅报错:', err);
    },
    complete: () => {
      console.log('订阅已完成');
    },
  });
};

// 组件卸载时自动取消订阅
useEffect(() => {
  return () => {
    if (subscriptionInstance) {
      subscriptionInstance.unsubscribe();
    }
  };
}, []);

替代方案:通过useSubscription钩子控制订阅时机

若更倾向于使用官方钩子,可以通过skip参数控制是否自动订阅,在按钮点击时切换订阅状态:

import { useState } from 'react';
import { useSubscription } from '@apollo/client';

const [isSubscribed, setIsSubscribed] = useState(false);

const { data, error, loading } = useSubscription(BULK_CREATE_PROCESS_DETAILS, {
  variables: {
    id: { userId: id },
  },
  skip: !isSubscribed, // skip为true时不执行订阅
  onData: ({ data }) => {
    console.log('订阅数据:', data);
  },
});

// 按钮点击触发订阅
const handleSubscribe = () => {
  setIsSubscribed(true);
};

// 停止订阅时调用
const handleUnsubscribe = () => {
  setIsSubscribed(false);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:30:46