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

如何在Svelte中处理HTTP请求过期及未捕获异常问题?

解决Svelte中AbortController中止请求的未捕获异常问题

1. 在API封装层统一捕获中止异常

既然所有请求都通过同一个类处理,直接在这个类的请求方法里统一加try/catch,专门过滤AbortError(浏览器中对应DOMException,name属性为AbortError)。这样所有组件调用API时,就不用各自重复处理中止异常了。

示例代码:

class ApiService {
  #abortControllers = new Map();

  async get(url, options = {}) {
    // 中止同URL的未完成请求
    this.#abortControllers.get(url)?.abort();
    
    const controller = new AbortController();
    this.#abortControllers.set(url, controller);

    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal
      });

      // 请求成功后清理控制器
      this.#abortControllers.delete(url);
      return await response.json();
    } catch (err) {
      // 仅忽略中止异常,其他错误正常抛出让上层处理
      if (err.name === 'AbortError') {
        console.debug(`请求 ${url} 已被中止`);
        // 返回标识值让组件区分“中止”和“正常失败”
        return null;
      }
      throw err;
    }
  }
}

之后在Svelte的effect里调用api.get()时,即使请求被中止,也只会返回null,不会抛出未捕获异常,组件可根据返回值自行判断后续逻辑。

2. 封装Svelte专用的请求Effect工具

如果不想修改API层,可以写一个通用的请求Effect工具,把中止异常的捕获逻辑封装进去,组件直接调用即可。

示例:

import { onMount, onDestroy } from 'svelte';

export function fetchWithAbortEffect(url, onSuccess) {
  let controller;

  const loadData = async () => {
    // 先中止上一次请求
    controller?.abort();
    controller = new AbortController();

    try {
      const res = await fetch(url, { signal: controller.signal });
      const data = await res.json();
      onSuccess(data);
    } catch (err) {
      // 只过滤中止异常,其他错误抛出让组件处理
      if (err.name !== 'AbortError') throw err;
    }
  };

  onMount(loadData);
  onDestroy(() => controller?.abort());
}

组件中使用:

<script>
  import { fetchWithAbortEffect } from './utils.js';
  let data;

  fetchWithAbortEffect('/api/list', (result) => {
    data = result;
  });
</script>

{#if data}
  <ul>
    {#each data as item}
      <li>{item.name}</li>
    {/each}
  </ul>
{:else}
  <p>加载中...</p>
{/if}

3. 利用Svelte的{#await}语法过滤中止异常

对于组件内直接发起的请求,可以用Svelte的{#await}块结合条件判断,只处理非中止类的错误。

示例:

<script>
  import { ApiService } from './api.js';
  const api = new ApiService();
  let data;
  let loadPromise = api.get('/api/detail');
</script>

{#await loadPromise}
  <p>加载中...</p>
{:then result}
  {#if result}
    <div>{JSON.stringify(result)}</div>
  {/if}
{:catch err}
  {#if err.name !== 'AbortError'}
    <p>加载失败:{err.message}</p>
  {/if}
{/await}

这里通过:catch块过滤掉中止异常,避免在请求被中止时显示错误提示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:15:03