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

在Vue3 Composition API中终止Apollo待处理查询求助

取消Apollo Query结果返回的可行方案

以下是几种经过验证的取消Apollo Query的有效方法,针对不同场景选择合适的方案:

1. 通过skip变量直接中止查询

这是最常用的控制方式,当skip设为true时,不仅不会发起新查询,正在进行中的请求也会被中止,且不会返回结果。

import { useQuery } from '@apollo/client';
import GET_DATA_QUERY from './queries/GetData';

function DataComponent({ shouldCancel }) {
  const { data, loading } = useQuery(GET_DATA_QUERY, {
    skip: shouldCancel, // 布尔值控制是否取消查询
    variables: { id: 'target-id' }
  });

  // 当shouldCancel为true时,data会保持之前的值或undefined,不会更新为新查询结果
  return (
    <div>
      {loading && <p>加载中...</p>}
      {data && !shouldCancel && <p>{data.content}</p>}
    </div>
  );
}

2. 手动调用查询的cancel方法

如果使用useLazyQuery或手动发起查询,可以获取到查询的cancel函数,主动调用即可中止请求。

针对useLazyQuery的场景:

import { useLazyQuery } from '@apollo/client';
import GET_DATA_QUERY from './queries/GetData';

function LazyDataComponent() {
  const [fetchData, { data, loading }] = useLazyQuery(GET_DATA_QUERY);
  let cancelQuery;

  const handleFetch = async () => {
    // 发起查询时获取cancel函数
    const queryResult = await fetchData({ variables: { id: 'target-id' } });
    cancelQuery = queryResult.cancel;
  };

  const handleCancel = () => {
    if (cancelQuery) {
      cancelQuery(); // 主动取消查询
    }
  };

  return (
    <div>
      <button onClick={handleFetch}>获取数据</button>
      <button onClick={handleCancel} disabled={!loading}>取消请求</button>
      {loading && <p>加载中...</p>}
      {data && <p>{data.content}</p>}
    </div>
  );
}

手动通过Apollo Client发起查询的场景:

import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: '/graphql',
  cache: new InMemoryCache(),
});

// 发起查询并保存引用
const queryRef = client.query({
  query: GET_DATA_QUERY,
  variables: { id: 'target-id' }
});

// 需要取消时调用
queryRef.cancel();

3. 使用AbortController控制请求

通过Apollo Client的context配置传入AbortController的signal,利用浏览器原生的中断机制取消请求。

import { useQuery } from '@apollo/client';
import GET_DATA_QUERY from './queries/GetData';

function AbortableComponent() {
  const abortController = new AbortController();
  const { data, loading } = useQuery(GET_DATA_QUERY, {
    variables: { id: 'target-id' },
    context: {
      fetchOptions: {
        signal: abortController.signal, // 绑定中断信号
      },
    },
  });

  const handleCancel = () => {
    abortController.abort(); // 触发中断
  };

  return (
    <div>
      <button onClick={handleCancel} disabled={!loading}>取消请求</button>
      {loading && <p>加载中...</p>}
      {data && <p>{data.content}</p>}
    </div>
  );
}

4. 组件卸载时自动取消查询

在组件卸载前取消订阅或中止查询,避免组件卸载后仍收到结果导致错误。

import { useApolloClient } from '@apollo/client';
import { useEffect } from 'react';
import GET_DATA_QUERY from './queries/GetData';

function AutoCancelComponent({ itemId }) {
  const client = useApolloClient();

  useEffect(() => {
    const querySubscription = client.watchQuery({
      query: GET_DATA_QUERY,
      variables: { id: itemId },
    }).subscribe({
      next: (result) => console.log('数据更新:', result.data),
      error: (err) => console.error('查询错误:', err),
    });

    // 组件卸载时取消订阅,同时中止查询
    return () => {
      querySubscription.unsubscribe();
    };
  }, [client, itemId]);

  return <div>组件内容</div>;
}

注意事项

  • 确保你的Apollo Client版本在3.0+,旧版本部分方法可能不兼容
  • 如果缓存中已有查询数据,skip设为true不会清除缓存,若需清除可调用client.cache.evict({ query: GET_DATA_QUERY, variables: { id: 'target-id' } })
  • 主动取消查询后,错误对象会包含canceled: true属性,可通过error.graphQLErrors.some(e => e.extensions?.canceled)判断是否为主动取消

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:15:34