From a5446b8c750477a32390596be4a069cbeaf2089d Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:30:26 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=B9=E6=AC=A1?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E8=84=9A=E6=9C=AC=E7=9A=84=20timeout,=20?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E4=B8=80=E4=B8=AA=E8=84=9A=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=97=B6=E9=97=B4=E5=A4=AA=E9=95=BF=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E6=89=80=E6=9C=89=E8=84=9A=E6=9C=AC=E6=A3=80=E6=9F=A5=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/script.ts | 39 +++++++++++++++++------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 227be28d1..5b7eb512a 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -10,6 +10,7 @@ import { getBrowserType, getStorageName, openInCurrentTab, + sleep, stringMatching, } from "@App/pkg/utils/utils"; import { ltever } from "@App/pkg/utils/semver"; @@ -764,17 +765,33 @@ export class ScriptService { setTimeout(resolve, Math.round(MIN_DELAY + ((++i / n + Math.random()) / 2) * (MAX_DELAY - MIN_DELAY))) ); - return Promise.all( - (uuids as string[]).map(async (uuid, _idx) => { - const script = scripts[_idx]; - const res = - !script || script.uuid !== uuid || !checkScripts.includes(script) - ? false - : await this._checkUpdateAvailable(script, delayFn); - if (!res) return false; - return res; - }) - ); + const results = new Map< + string, + | false + | { + updateAvailable: true; + code: string; + metadata: Partial>; + } + >(); + + await Promise.race([ + sleep(300_000), // 5 minutes + Promise.allSettled( + (uuids as string[]).map(async (uuid, _idx) => { + results.set(uuid, false); // 確保次序 + const script = scripts[_idx]; + const res = + !script || script.uuid !== uuid || !checkScripts.includes(script) + ? false + : await this._checkUpdateAvailable(script, delayFn); + if (!res) return false; + results.set(uuid, res); + return res; + }) + ), + ]); + return [...results.values()]; } async _checkUpdateAvailable( From b325afc1219e4df0bfbb8122ef240ee00ad474b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Mon, 16 Mar 2026 15:40:12 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=9B=B4=E6=96=B0=E8=B6=85=E6=97=B6=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=E7=9A=84=204=20=E4=B8=AA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fetchScriptBody 添加 AbortSignal 支持 - 繁体转简体:確保次序 → 确保顺序 - 用 setTimeout+clearTimeout 替代 sleep,超时后正确清理 - 超时时通过 AbortController 中止进行中的请求 - Map 预初始化确保返回顺序一致 --- src/app/service/service_worker/script.ts | 38 +++++++++++++++++++----- src/pkg/utils/script.ts | 3 +- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 6d30efaeb..baf968383 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -10,7 +10,6 @@ import { getBrowserType, getStorageName, openInCurrentTab, - sleep, stringMatching, } from "@App/pkg/utils/utils"; import { ltever } from "@App/pkg/utils/semver"; @@ -773,6 +772,8 @@ export class ScriptService { setTimeout(resolve, Math.round(MIN_DELAY + ((++i / n + Math.random()) / 2) * (MAX_DELAY - MIN_DELAY))) ); + const CHECK_UPDATE_TIMEOUT_MS = 300_000; // 5 分钟超时 + const results = new Map< string, | false @@ -783,21 +784,37 @@ export class ScriptService { } >(); + // 预初始化 Map 确保顺序 + for (const uuid of uuids as string[]) { + results.set(uuid, false); + } + + const abortController = new AbortController(); + let timeoutId: ReturnType; + + const timeoutPromise = new Promise((resolve) => { + timeoutId = setTimeout(() => { + abortController.abort(); + resolve(); + }, CHECK_UPDATE_TIMEOUT_MS); + }); + await Promise.race([ - sleep(300_000), // 5 minutes + timeoutPromise, Promise.allSettled( (uuids as string[]).map(async (uuid, _idx) => { - results.set(uuid, false); // 確保次序 const script = scripts[_idx]; const res = !script || script.uuid !== uuid || !checkScripts.includes(script) ? false - : await this._checkUpdateAvailable(script, delayFn); + : await this._checkUpdateAvailable(script, delayFn, abortController.signal); if (!res) return false; results.set(uuid, res); return res; }) - ), + ).finally(() => { + clearTimeout(timeoutId); + }), ]); return [...results.values()]; } @@ -809,7 +826,8 @@ export class ScriptService { checkUpdateUrl?: string; metadata: Partial>; }, - delayFn?: () => Promise + delayFn?: () => Promise, + signal?: AbortSignal ): Promise { const { uuid, name, checkUpdateUrl } = script; @@ -821,8 +839,12 @@ export class ScriptService { name, }); try { - if (delayFn) await delayFn(); - const code = await fetchScriptBody(checkUpdateUrl); + if (delayFn) { + if (signal?.aborted) return false; + await delayFn(); + } + if (signal?.aborted) return false; + const code = await fetchScriptBody(checkUpdateUrl, signal); const metadata = parseMetadata(code); if (!metadata) { logger.error("parse metadata failed"); diff --git a/src/pkg/utils/script.ts b/src/pkg/utils/script.ts index 76a5a5600..4f1ba4c57 100644 --- a/src/pkg/utils/script.ts +++ b/src/pkg/utils/script.ts @@ -46,8 +46,9 @@ export function parseMetadata(code: string): SCMetadata | null { } // 从网址取得脚本代码 -export async function fetchScriptBody(url: string): Promise { +export async function fetchScriptBody(url: string, signal?: AbortSignal): Promise { const resp = await fetch(url, { + signal, headers: { "Cache-Control": "no-cache", },