代码片段管理技能Skill snippet-manager

这个技能用于帮助开发者高效管理代码片段,支持保存、组织、分类、搜索和检索功能,涵盖前端、后端、数据库、测试等多种开发场景,提升代码复用和开发效率。关键词:代码片段管理、代码组织、智能搜索、标签分类、软件开发工具、代码复用、开发效率提升。

其他 0 次安装 0 次浏览 更新于 3/11/2026

name: 代码片段管理器 description: 使用标签、分类和智能搜索功能保存、组织、搜索和检索代码片段…

代码片段管理器技能

使用标签、分类和智能搜索功能保存、组织、搜索和检索代码片段。

使用说明

您是一个代码片段管理专家。调用时:

  1. 保存代码片段

    • 提取可重用的代码模式
    • 添加元数据(语言、标签、描述)
    • 按类别和用例组织
    • 对片段变体进行版本控制
  2. 搜索和检索

    • 按语言、标签或关键词搜索
    • 查找相似模式
    • 根据上下文建议相关片段
    • 按框架或库过滤
  3. 片段组织

    • 逻辑分类片段
    • 使用相关关键词标记
    • 分组相关片段
    • 创建片段集合
  4. 片段增强

    • 添加使用示例
    • 记录参数和选项
    • 包括边缘情况
    • 提供替代实现

片段类别

  • 语言基础:常见模式、惯用语、语法助手
  • 数据结构:数组、对象、映射、集合操作
  • 算法:排序、搜索、递归、动态规划
  • API模式:REST客户端、错误处理、身份验证
  • 数据库:查询、迁移、ORM模式
  • 测试:测试设置、模拟、断言
  • React/Vue/Angular:组件模式、钩子、指令
  • Node.js:Express中间件、流、文件操作
  • Python:装饰器、上下文管理器、生成器
  • DevOps:Docker、CI/CD、部署脚本
  • 实用工具:日期/时间、字符串操作、验证

使用示例

@snippet-manager 保存API错误处理程序
@snippet-manager --search "react hooks"
@snippet-manager --category 测试
@snippet-manager --language python
@snippet-manager --tag async
@snippet-manager --collection "身份验证模式"

片段格式

基本片段结构

# 片段:异步错误处理程序包装器

**语言**:JavaScript/TypeScript
**类别**:错误处理
**标签**:async, error-handling, middleware, express
**框架**:Express.js
**用例**:包装异步路由处理程序以捕获错误

## 代码

```javascript
const asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

// 使用
app.get('/users/:id', asyncHandler(async (req, res) => {
  const user = await User.findById(req.params.id);
  res.json(user);
}));

参数

  • fn:要包装的异步函数 (Request, Response, NextFunction) => Promise<void>

返回值

Express中间件函数,处理承诺拒绝

备注

  • 消除路由处理程序中的try-catch块
  • 将错误传递给Express错误处理中间件
  • 适用于任何异步函数

相关片段


## JavaScript/TypeScript片段

### 防抖函数

```javascript
// 片段:防抖
// 类别:性能
// 标签:debounce, performance, optimization

function debounce(func, wait, immediate = false) {
  let timeout;

  return function executedFunction(...args) {
    const later = () => {
      timeout = null;
      if (!immediate) func.apply(this, args);
    };

    const callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(this, args);
  };
}

// 使用
const handleSearch = debounce((query) => {
  fetchResults(query);
}, 300);

// 在React中
const [searchTerm, setSearchTerm] = useState('');

const debouncedSearch = useMemo(
  () => debounce((term) => {
    // 执行搜索
    console.log('搜索:', term);
  }, 500),
  []
);

useEffect(() => {
  debouncedSearch(searchTerm);
}, [searchTerm, debouncedSearch]);

深克隆对象

// 片段:深克隆
// 类别:数据结构
// 标签:clone, deep-copy, objects

// 方法1:JSON(仅简单对象)
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));

// 方法2:结构化克隆(现代浏览器/Node.js)
const deepClone2 = (obj) => structuredClone(obj);

// 方法3:自定义递归(处理复杂类型)
function deepClone3(obj, hash = new WeakMap()) {
  if (Object(obj) !== obj) return obj; // 基本类型
  if (hash.has(obj)) return hash.get(obj); // 循环引用

  const result = Array.isArray(obj)
    ? []
    : obj.constructor
      ? new obj.constructor()
      : Object.create(null);

  hash.set(obj, result);

  return Object.assign(
    result,
    ...Object.keys(obj).map(key => ({
      [key]: deepClone3(obj[key], hash)
    }))
  );
}

// 使用
const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const cloned = deepClone(original);
cloned.b.c = 999; // original.b.c仍为2

指数退避重试

// 片段:指数退避重试
// 类别:错误处理
// 标签:retry, async, error-handling, resilience

async function retryWithBackoff<T>(
  fn: () => Promise<T>,
  options: {
    maxRetries?: number;
    initialDelay?: number;
    maxDelay?: number;
    factor?: number;
  } = {}
): Promise<T> {
  const {
    maxRetries = 3,
    initialDelay = 1000,
    maxDelay = 30000,
    factor = 2,
  } = options;

  let lastError: Error;
  let delay = initialDelay;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error as Error;

      if (attempt === maxRetries) {
        throw new Error(
          `在${maxRetries}次重试后失败:${lastError.message}`
        );
      }

      console.log(`第${attempt + 1}次尝试失败,${delay}毫秒后重试...`);
      await new Promise(resolve => setTimeout(resolve, delay));

      delay = Math.min(delay * factor, maxDelay);
    }
  }

  throw lastError!;
}

// 使用
const data = await retryWithBackoff(
  () => fetch('https://api.example.com/data').then(r => r.json()),
  { maxRetries: 5, initialDelay: 500 }
);

带过期的本地存储

// 片段:带过期的本地存储
// 类别:浏览器API
// 标签:localstorage, cache, expiry

const storage = {
  set(key, value, expiryMs = null) {
    const item = {
      value,
      expiry: expiryMs ? Date.now() + expiryMs : null,
    };
    localStorage.setItem(key, JSON.stringify(item));
  },

  get(key) {
    const itemStr = localStorage.getItem(key);
    if (!itemStr) return null;

    const item = JSON.parse(itemStr);

    if (item.expiry && Date.now() > item.expiry) {
      localStorage.removeItem(key);
      return null;
    }

    return item.value;
  },

  remove(key) {
    localStorage.removeItem(key);
  },

  clear() {
    localStorage.clear();
  },
};

// 使用
storage.set('user', { id: 1, name: 'John' }, 3600000); // 1小时
const user = storage.get('user');

React片段

自定义useDebounce钩子

// 片段:useDebounce钩子
// 类别:React钩子
// 标签:react, hooks, debounce, performance

import { useEffect, useState } from 'react';

function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

// 使用
function SearchComponent() {
  const [searchTerm, setSearchTerm] = useState('');
  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  useEffect(() => {
    if (debouncedSearchTerm) {
      // 执行搜索
      fetchResults(debouncedSearchTerm);
    }
  }, [debouncedSearchTerm]);

  return (
    <input
      value={searchTerm}
      onChange={(e) => setSearchTerm(e.target.value)}
    />
  );
}

自定义useAsync钩子

// 片段:useAsync钩子
// 类别:React钩子
// 标签:react, hooks, async, data-fetching

import { useEffect, useState, useCallback } from 'react';

type Status = 'idle' | 'loading' | 'success' | 'error';

interface AsyncState<T> {
  status: Status;
  data: T | null;
  error: Error | null;
}

function useAsync<T>(
  asyncFunction: () => Promise<T>,
  immediate = true
) {
  const [state, setState] = useState<AsyncState<T>>({
    status: 'idle',
    data: null,
    error: null,
  });

  const execute = useCallback(async () => {
    setState({ status: 'loading', data: null, error: null });

    try {
      const data = await asyncFunction();
      setState({ status: 'success', data, error: null });
      return data;
    } catch (error) {
      setState({ status: 'error', data: null, error: error as Error });
      throw error;
    }
  }, [asyncFunction]);

  useEffect(() => {
    if (immediate) {
      execute();
    }
  }, [execute, immediate]);

  return { ...state, execute };
}

// 使用
function UserProfile({ userId }) {
  const { status, data, error } = useAsync(
    () => fetch(`/api/users/${userId}`).then(r => r.json()),
    true
  );

  if (status === 'loading') return <div>加载中...</div>;
  if (status === 'error') return <div>错误:{error.message}</div>;
  if (status === 'success') return <div>用户:{data.name}</div>;

  return null;
}

自定义useLocalStorage钩子

// 片段:useLocalStorage钩子
// 类别:React钩子
// 标签:react, hooks, localstorage, persistence

import { useState, useEffect } from 'react';

function useLocalStorage<T>(
  key: string,
  initialValue: T
): [T, (value: T | ((val: T) => T)) => void] {
  // 从本地存储读取,然后解析存储的JSON或返回初始值
  const readValue = (): T => {
    if (typeof window === 'undefined') {
      return initialValue;
    }

    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.warn(`读取本地存储键"${key}"时出错:`, error);
      return initialValue;
    }
  };

  const [storedValue, setStoredValue] = useState<T>(readValue);

  const setValue = (value: T | ((val: T) => T)) => {
    try {
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;

      setStoredValue(valueToStore);

      if (typeof window !== 'undefined') {
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      }
    } catch (error) {
      console.warn(`设置本地存储键"${key}"时出错:`, error);
    }
  };

  useEffect(() => {
    setStoredValue(readValue());
  }, []);

  return [storedValue, setValue];
}

// 使用
function App() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');

  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      当前主题:{theme}
    </button>
  );
}

Python片段

重试装饰器

# 片段:重试装饰器
# 类别:错误处理
# 标签:python, decorator, retry, error-handling

import time
import functools
from typing import Callable, Type

def retry(
    max_attempts: int = 3,
    delay: float = 1.0,
    backoff: float = 2.0,
    exceptions: tuple[Type[Exception], ...] = (Exception,)
):
    """
    指数退避重试装饰器

    参数:
        max_attempts:最大重试尝试次数
        delay:初始重试延迟(秒)
        backoff:每次重试后延迟的乘数
        exceptions:要捕获的异常元组
    """
    def decorator(func: Callable):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            current_delay = delay
            last_exception = None

            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_exception = e
                    if attempt == max_attempts - 1:
                        raise

                    print(f"第{attempt + 1}次尝试失败:{e}")
                    print(f"{current_delay}秒后重试...")
                    time.sleep(current_delay)
                    current_delay *= backoff

            raise last_exception

        return wrapper
    return decorator

# 使用
@retry(max_attempts=5, delay=0.5, exceptions=(ConnectionError, TimeoutError))
def fetch_data(url: str):
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    return response.json()

计时上下文管理器

# 片段:计时上下文管理器
# 类别:性能
# 标签:python, context-manager, timing, profiling

import time
from contextlib import contextmanager
from typing import Optional

@contextmanager
def timer(name: Optional[str] = None):
    """
    用于计时代码执行的上下文管理器

    使用:
        with timer("数据库查询"):
            result = db.query(...)
    """
    start = time.perf_counter()
    try:
        yield
    finally:
        elapsed = time.perf_counter() - start
        label = f"{name}: " if name else ""
        print(f"{label}经过时间:{elapsed:.4f}秒")

# 使用
with timer("API调用"):
    response = requests.get("https://api.example.com/data")
    data = response.json()

# 替代:作为装饰器
def timed(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__}花费了{elapsed:.4f}秒")
        return result
    return wrapper

@timed
def process_data(data):
    # 处理数据
    pass

使用LRU缓存的记忆化

# 片段:记忆化
# 类别:性能
# 标签:python, cache, memoization, optimization

from functools import lru_cache, wraps
import pickle
import hashlib

# 简单记忆化与lru_cache
@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# 自定义记忆化用于不可哈希参数
def memoize(func):
    cache = {}

    @wraps(func)
    def wrapper(*args, **kwargs):
        # 从参数创建可哈希键
        key = hashlib.md5(
            pickle.dumps((args, tuple(sorted(kwargs.items()))))
        ).hexdigest()

        if key not in cache:
            cache[key] = func(*args, **kwargs)

        return cache[key]

    wrapper.cache_clear = lambda: cache.clear()
    wrapper.cache_info = lambda: f"缓存大小:{len(cache)}"

    return wrapper

# 使用不可哈希类型(列表、字典)
@memoize
def expensive_computation(data: list[int]) -> int:
    return sum(x ** 2 for x in data)

result = expensive_computation([1, 2, 3, 4, 5])

Node.js片段

速率限制器中间件

// 片段:速率限制器
// 类别:中间件
// 标签:nodejs, express, rate-limiting, security

class RateLimiter {
  constructor(options = {}) {
    this.windowMs = options.windowMs || 60000; // 1分钟
    this.maxRequests = options.maxRequests || 100;
    this.requests = new Map();
  }

  middleware() {
    return (req, res, next) => {
      const key = req.ip || req.connection.remoteAddress;
      const now = Date.now();

      if (!this.requests.has(key)) {
        this.requests.set(key, []);
      }

      const userRequests = this.requests.get(key);

      // 移除窗口外的旧请求
      const validRequests = userRequests.filter(
        timestamp => now - timestamp < this.windowMs
      );

      if (validRequests.length >= this.maxRequests) {
        const oldestRequest = validRequests[0];
        const resetTime = oldestRequest + this.windowMs;
        const retryAfter = Math.ceil((resetTime - now) / 1000);

        res.set('Retry-After', retryAfter.toString());
        return res.status(429).json({
          error: '请求过多',
          retryAfter: retryAfter,
        });
      }

      validRequests.push(now);
      this.requests.set(key, validRequests);

      res.set('X-RateLimit-Limit', this.maxRequests.toString());
      res.set('X-RateLimit-Remaining',
        (this.maxRequests - validRequests.length).toString()
      );

      next();
    };
  }

  // 定期清理旧条目
  cleanup() {
    const now = Date.now();
    for (const [key, timestamps] of this.requests.entries()) {
      const valid = timestamps.filter(t => now - t < this.windowMs);
      if (valid.length === 0) {
        this.requests.delete(key);
      } else {
        this.requests.set(key, valid);
      }
    }
  }
}

// 使用
const limiter = new RateLimiter({
  windowMs: 15 * 60 * 1000, // 15分钟
  maxRequests: 100,
});

app.use('/api', limiter.middleware());

// 每5分钟清理
setInterval(() => limiter.cleanup(), 5 * 60 * 1000);

流管道助手

// 片段:流管道
// 类别:流
// 标签:nodejs, streams, pipeline, files

const { pipeline } = require('stream');
const { promisify } = require('util');
const fs = require('fs');
const zlib = require('zlib');
const { Transform } = require('stream');

const pipelineAsync = promisify(pipeline);

// 自定义转换流
class LineCounter extends Transform {
  constructor(options) {
    super(options);
    this.lineCount = 0;
  }

  _transform(chunk, encoding, callback) {
    const lines = chunk.toString().split('
').length - 1;
    this.lineCount += lines;
    this.push(chunk);
    callback();
  }
}

// 使用:压缩文件并计数行数
async function compressAndCount(inputFile, outputFile) {
  const counter = new LineCounter();

  await pipelineAsync(
    fs.createReadStream(inputFile),
    counter,
    zlib.createGzip(),
    fs.createWriteStream(outputFile)
  );

  console.log(`处理了${counter.lineCount}行`);
  return counter.lineCount;
}

// 使用:处理大型CSV
async function processCsv(inputFile) {
  const processLine = new Transform({
    transform(chunk, encoding, callback) {
      const lines = chunk.toString().split('
');
      const processed = lines
        .map(line => line.toUpperCase())
        .join('
');
      callback(null, processed);
    }
  });

  await pipelineAsync(
    fs.createReadStream(inputFile),
    processLine,
    fs.createWriteStream('output.csv')
  );
}

SQL片段

安全Upsert模式

-- 片段:Upsert(插入或更新)
-- 类别:数据库
-- 标签:sql, upsert, postgresql

-- PostgreSQL
INSERT INTO users (id, email, name, updated_at)
VALUES (1, 'user@example.com', 'John Doe', NOW())
ON CONFLICT (id)
DO UPDATE SET
  email = EXCLUDED.email,
  name = EXCLUDED.name,
  updated_at = NOW()
RETURNING *;

-- 多行upsert
INSERT INTO products (sku, name, price)
VALUES
  ('SKU001', 'Product 1', 29.99),
  ('SKU002', 'Product 2', 39.99)
ON CONFLICT (sku)
DO UPDATE SET
  name = EXCLUDED.name,
  price = EXCLUDED.price,
  updated_at = NOW();

分页查询

-- 片段:高效分页
-- 类别:数据库
-- 标签:sql, pagination, performance

-- 基于偏移(简单但对于大偏移较慢)
SELECT *
FROM posts
ORDER BY created_at DESC
LIMIT 20 OFFSET 40; -- 第3页

-- 基于游标(更高效)
SELECT *
FROM posts
WHERE created_at < '2024-01-01 12:00:00'
ORDER BY created_at DESC
LIMIT 20;

-- 键集分页(最佳性能)
SELECT *
FROM posts
WHERE (created_at, id) < ('2024-01-01 12:00:00', 12345)
ORDER BY created_at DESC, id DESC
LIMIT 20;

最佳实践

片段组织

  • 一致命名:使用清晰、描述性名称
  • 全面标签:添加多个相关标签
  • 版本跟踪:跟踪片段版本
  • 依赖项:记录所需库

文档

  • 使用示例:显示真实世界用法
  • 参数文档:记录所有参数
  • 边缘情况:提及限制和边缘情况
  • 替代方案:建议相关模式

维护

  • 定期审查:定期更新片段
  • 测试片段:确保片段仍有效
  • 弃用:标记过时片段
  • 贡献:与团队共享有用片段

片段管理工具

基于文件的存储

snippets/
├── javascript/
│   ├── async/
│   │   ├── retry.js
│   │   └── debounce.js
│   └── react/
│       ├── hooks/
│       └── components/
├── python/
│   ├── decorators/
│   └── context-managers/
└── sql/
    ├── queries/
    └── migrations/

元数据格式(frontmatter)

---
title: "异步重试与退避"
language: javascript
category: error-handling
tags: [async, retry, error-handling, resilience]
framework: nodejs
version: 1.2.0
author: team
created: 2024-01-15
updated: 2024-01-20
---

备注

  • 保持片段专注和单一用途
  • 在示例中包括错误处理
  • 记录性能特征
  • 保存前测试片段
  • 使用一致的编码风格
  • 为复杂逻辑添加注释
  • 进行更改时对片段进行版本控制
  • 在团队内共享片段
  • 定期清理过时片段