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

如何创建仅在另一数组Store新增项时执行代码的Svelte derived store

基于SvelteKit实现URL列表的增量异步处理方案

核心设计思路

用writable store存储用户维护的URL列表,通过derived store实现增量异步处理——仅对新增URL执行异步操作,同时维护已处理结果的缓存,避免重复请求。整个流程遵循Svelte声明式状态管理的风格,把异步逻辑封装在store内部,组件只需要关注状态的使用与交互。

具体实现步骤

1. 定义基础Store与异步处理函数

首先创建存储URL列表的writable store,以及处理单个URL的异步逻辑(示例为获取页面标题,可根据需求扩展):

// src/lib/stores.js
import { writable, derived } from 'svelte/store';

// 存储用户操作的URL列表
export const urlList = writable([]);

// 单个URL的异步处理逻辑,可根据需求扩展(比如解析内容、截图等)
async function processSingleUrl(url) {
  try {
    const response = await fetch(url);
    const html = await response.text();
    const titleMatch = html.match(/<title>(.*?)<\/title>/i);
    
    return {
      url,
      title: titleMatch ? titleMatch[1] : '无标题',
      status: 'success',
      error: null
    };
  } catch (err) {
    return {
      url,
      title: null,
      status: 'error',
      error: err.message
    };
  }
}

2. 实现增量处理的Derived Store

创建derived store,内部维护已处理结果的缓存,每次urlList更新时仅处理新增URL,合并结果并同步状态:

// src/lib/stores.js 继续添加
export const processedUrls = derived(urlList, ($urlList, set) => {
  // 缓存已处理的URL结果,避免重复执行异步操作
  const processedCache = new Map();

  // 初始化:处理初始加载的URL列表
  async function initProcess() {
    const initialResults = await Promise.all(
      $urlList.map(async url => {
        const result = await processSingleUrl(url);
        processedCache.set(url, result);
        return result;
      })
    );
    set(initialResults);
  }

  initProcess();

  // 订阅urlList的变化,处理新增URL
  return urlList.subscribe(async newUrls => {
    // 筛选出未被缓存的新增URL
    const unprocessedUrls = newUrls.filter(url => !processedCache.has(url));
    
    if (unprocessedUrls.length === 0) return;

    // 批量处理新增URL
    const newResults = await Promise.all(
      unprocessedUrls.map(async url => {
        const result = await processSingleUrl(url);
        processedCache.set(url, result);
        return result;
      })
    );

    // 保持结果列表与urlList顺序一致,同步状态
    const updatedResults = newUrls.map(url => processedCache.get(url));
    set(updatedResults);
  });
}, []);

3. 组件中使用Store实现交互

在组件中绑定URL的添加/删除操作,同时订阅processedUrls展示处理结果:

<!-- src/routes/+page.svelte -->
<script>
  import { urlList, processedUrls } from '$lib/stores';
  let inputUrl = '';

  function addNewUrl() {
    if (!inputUrl.trim()) return;
    $urlList = [...$urlList, inputUrl.trim()];
    inputUrl = '';
  }

  function removeTargetUrl(url) {
    $urlList = $urlList.filter(item => item !== url);
    // 删除操作触发urlList更新后,processedUrls会自动同步过滤结果
  }
</script>

<div class="url-manager">
  <div class="input-group">
    <input 
      bind:value={inputUrl} 
      placeholder="输入要处理的URL"
      type="url"
    />
    <button on:click={addNewUrl}>添加并处理</button>
  </div>

  <div class="results">
    <h3>处理结果</h3>
    {#each $processedUrls as result}
      <div class="result-card">
        <div class="url">{result.url}</div>
        {#if result.status === 'success'}
          <div class="success">标题:{result.title}</div>
        {:else}
          <div class="error">处理失败:{result.error}</div>
        {/if}
        <button on:click={() => removeTargetUrl(result.url)}>删除</button>
      </div>
    {/each}
  </div>
</div>

<style>
  .url-manager { max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
  .input-group { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }
  input { flex: 1; padding: 0.5rem; border: 1px solid #eee; border-radius: 4px; }
  button { padding: 0.5rem 1rem; cursor: pointer; }
  .result-card { padding: 1rem; border: 1px solid #eee; border-radius: 4px; margin: 0.5rem 0; }
  .success { color: #2ecc71; margin: 0.5rem 0; }
  .error { color: #e74c3c; margin: 0.5rem 0; }
</style>

关键细节说明

  • 增量处理:通过processedCache缓存已处理结果,仅对新增URL执行异步操作,大幅减少不必要的网络请求与计算。
  • 状态同步:当URL列表删除项时,processedUrls会自动根据最新的urlList重新生成结果,保持与源列表的一致性。
  • 错误隔离:单个URL处理失败不会影响其他URL,结果中保留错误信息,方便组件友好展示。
  • 组件解耦:异步逻辑完全封装在store内部,组件只需关注交互与结果渲染,符合Svelte的组件设计理念。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:50:37