feat(about): 为fetch请求添加超时控制功能

- 新增fetchWithTimeout方法支持请求超时控制
- 为GitHub用户数据请求添加5秒超时限制
- 为GitHub仓库数据请求添加5秒超时限制
- 为RSS数据请求添加5秒超时限制
- 为本地文章数据请求添加3秒超时限制
- 使用AbortController实现请求中断机制
- 优化请求失败时的错误处理流程
This commit is contained in:
hehh
2025-11-25 00:49:55 +08:00
parent 4a0aa67e5b
commit 9d766b0025

View File

@@ -224,6 +224,21 @@ class DataManager {
setTimeout(() => this.fetchBlog(), 0); setTimeout(() => this.fetchBlog(), 0);
} }
// 创建带超时的fetch函数
async fetchWithTimeout(url, options = {}) {
const { timeout = 5000 } = options;
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(id);
return response;
}
// 优先缓存 -> API -> 默认值 // 优先缓存 -> API -> 默认值
async fetchGithub() { async fetchGithub() {
const user = (window.SiteConfig?.github?.username) || 'listener-He'; const user = (window.SiteConfig?.github?.username) || 'listener-He';
@@ -240,14 +255,14 @@ class DataManager {
} }
try { try {
// Parallel Fetch // Parallel Fetch with timeout
const uRes = await fetch(`https://api.github.com/users/${user}`); const uRes = await this.fetchWithTimeout(`https://api.github.com/users/${user}`, { timeout: 5000 });
const userData = uRes.ok ? await uRes.json() : (window.SiteConfig?.defaults?.user); const userData = uRes.ok ? await uRes.json() : (window.SiteConfig?.defaults?.user);
let allRepos = []; let allRepos = [];
let page = 1; let page = 1;
const perPage = 100; const perPage = 100;
while (page <= 10) { // 最多抓取1000条直到满足条件或为空 while (page <= 10) { // 最多抓取1000条直到满足条件或为空
const rRes = await fetch(`https://api.github.com/users/${user}/repos?sort=stars&per_page=${perPage}&page=${page}`); const rRes = await this.fetchWithTimeout(`https://api.github.com/users/${user}/repos?sort=stars&per_page=${perPage}&page=${page}`, { timeout: 5000 });
if (!rRes.ok) break; if (!rRes.ok) break;
const repos = await rRes.json(); const repos = await rRes.json();
if (!Array.isArray(repos) || repos.length === 0) break; if (!Array.isArray(repos) || repos.length === 0) break;
@@ -342,8 +357,8 @@ class DataManager {
} }
try { try {
// 尝试从RSS获取 // 尝试从RSS获取,带超时设置
const response = await fetch(rssUrl); const response = await this.fetchWithTimeout(rssUrl, { timeout: 5000 });
if (!response.ok) throw new Error('RSS fetch failed'); if (!response.ok) throw new Error('RSS fetch failed');
const xmlText = await response.text(); const xmlText = await response.text();
@@ -385,7 +400,7 @@ class DataManager {
console.warn("RSS API Fail", e); console.warn("RSS API Fail", e);
// 降级到本地JSON文件 // 降级到本地JSON文件
try { try {
const response = await fetch('data/articles.json'); const response = await this.fetchWithTimeout('data/articles.json', { timeout: 3000 });
const data = await response.json(); const data = await response.json();
this.renderBlog(data); this.renderBlog(data);
} catch (e2) { } catch (e2) {