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

SvelteKit多加载源自动重试加载Spinner实现方案咨询

SvelteKit 加载Spinner + 自动重试最佳实践

核心思路

  • 用Svelte响应式状态统一控制Spinner的显示/隐藏
  • 封装通用重试工具函数,避免重复编写重试逻辑
  • 将地图初始化、数据请求拆分为独立异步任务,通过Promise串联确保执行顺序

具体实现步骤

1. 定义响应式状态

在组件中声明控制Spinner的状态,同时可添加错误提示状态提升用户体验:

<script>
  import { onMount } from 'svelte';
  // 控制Spinner显示状态
  let isLoading = true;
  // 可选:显示加载失败提示
  let errorTip = '';
</script>

<!-- 加载Spinner组件 -->
{#if isLoading}
  <div class="loading-spinner">
    <div class="spinner-icon"></div>
    <p>{errorTip || '加载中...'}</p>
  </div>
{/if}

<!-- MapLibre地图容器 -->
<div id="map-container" class="map-box"></div>

2. 封装通用重试函数

写一个通用异步重试工具,支持自定义重试延迟,默认5秒;无限重试直到任务成功:

/**
 * 异步任务自动重试工具
 * @param {Function} fn - 需要重试的异步函数
 * @param {number} delay - 重试间隔(毫秒),默认5000
 */
async function retryAsync(fn, delay = 5000) {
  while (true) {
    try {
      return await fn();
    } catch (err) {
      console.error('加载失败,即将重试:', err);
      errorTip = '加载失败,5秒后重试...';
      // 等待指定延迟后再次执行任务
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

3. 封装MapLibre地图加载函数

将地图初始化逻辑封装为Promise,把事件回调转为异步逻辑:

async function initMapLibre() {
  return new Promise((resolve, reject) => {
    const map = new maplibregl.Map({
      container: 'map-container',
      style: 'https://demotiles.maplibre.org/style.json', // 替换为你的地图样式URL
      center: [116.397428, 39.90923], // 替换为你的初始中心点
      zoom: 10
    });

    // 地图加载成功时resolve
    map.on('load', () => resolve(map));
    // 地图加载失败时reject
    map.on('error', (error) => reject(error));
  });
}

4. 封装额外数据请求函数

将数据fetch逻辑封装为独立异步函数,统一错误处理:

async function fetchExtraDataset() {
  const response = await fetch('你的数据API地址');
  if (!response.ok) {
    throw new Error(`请求失败,状态码: ${response.status}`);
  }
  return await response.json();
}

5. 串联加载流程并更新状态

在onMount中调用重试函数,按顺序执行地图加载、数据请求,完成后关闭Spinner:

onMount(async () => {
  try {
    // 先重试加载地图,直到成功
    const map = await retryAsync(initMapLibre);
    // 地图加载完成后,继续重试加载额外数据
    const extraData = await retryAsync(fetchExtraDataset);

    // 所有加载任务完成,关闭Spinner
    isLoading = false;
    errorTip = '';

    // 这里可以添加地图数据渲染逻辑,比如添加自定义图层
    map.addSource('custom-data', {
      type: 'geojson',
      data: extraData
    });
    // 示例:添加填充图层
    map.addLayer({
      id: 'custom-layer',
      type: 'fill',
      source: 'custom-data',
      paint: {
        'fill-color': '#888888',
        'fill-opacity': 0.4
      }
    });
  } catch (finalError) {
    // 若设置了最大重试次数,可在这里处理最终失败的情况(本示例为无限重试,此分支不会触发)
    errorTip = '加载最终失败,请刷新页面重试';
    isLoading = false;
    console.error('最终加载失败:', finalError);
  }
});

6. 添加上样式(可选)

给Spinner和地图容器添加基础样式,提升视觉体验:

.loading-spinner {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #ffffff;
  padding: 1.5rem 2rem;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  z-index: 9999;
}

.spinner-icon {
  width: 32px;
  height: 32px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.map-box {
  width: 100%;
  height: 100vh;
}

方案优势

  • 逻辑复用:通用重试函数可复用在任何需要重试的异步任务中,减少冗余代码
  • 状态可控:通过Svelte响应式状态自动绑定Spinner显示,无需手动操作DOM
  • 流程清晰:Promise串联任务确保地图加载完成后才请求数据,符合业务逻辑
  • 容错性强:自动重试直到任务成功,满足需求中持续重试的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:26:03