From 63a7cb347b11880ac0095ef3b6446062248c88a9 Mon Sep 17 00:00:00 2001 From: yw1573 Date: Fri, 10 Apr 2026 09:11:10 +0800 Subject: [PATCH] fix: cancel parse requests when modal is closed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 点击取消解析时,清空 PQueue 队列并中断正在进行的请求。 Co-Authored-By: Claude Opus 4.6 --- internal/bilibili/video.go | 18 ++++++++++++++++-- web/src/work/view/parseModal.ts | 13 ++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/internal/bilibili/video.go b/internal/bilibili/video.go index f12c54b..1b59f8f 100644 --- a/internal/bilibili/video.go +++ b/internal/bilibili/video.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "math/rand" "strconv" "strings" @@ -80,11 +81,24 @@ func (client *BiliClient) GetPlayInfo(bvid string, cid int) (*PlayInfo, error) { if err != nil { return nil, err } - body := BaseResV2{} - err = json.NewDecoder(response.Body).Decode(&body) + defer response.Body.Close() + + // 读取响应体用于调试 + bodyBytes, err := io.ReadAll(response.Body) if err != nil { return nil, err } + + body := BaseResV2{} + err = json.Unmarshal(bodyBytes, &body) + if err != nil { + // 返回更详细的错误信息 + preview := string(bodyBytes) + if len(preview) > 200 { + preview = preview[:200] + "..." + } + return nil, fmt.Errorf("JSON解析失败,响应内容: %s", preview) + } if body.Code != 0 { return nil, errors.New(body.Message) } diff --git a/web/src/work/view/parseModal.ts b/web/src/work/view/parseModal.ts index 092ff9c..0e9694c 100644 --- a/web/src/work/view/parseModal.ts +++ b/web/src/work/view/parseModal.ts @@ -42,6 +42,8 @@ export class ParseModalComp implements VanComponent { currentController?: AbortController + parseQueue?: PQueue + allPlayInfo: State<{ page: PageInParseResult info: PlayInfo | null @@ -105,6 +107,8 @@ export class ParseModalComp implements VanComponent { controller.abort() } this.abortControllers = [] + // 清空解析队列 + this.parseQueue?.clear() }) this.element.addEventListener('show.bs.modal', () => { @@ -116,13 +120,19 @@ export class ParseModalComp implements VanComponent { async start() { this.finishCount.val = 0 this.errorList.val = [] - const queue = new PQueue({ concurrency: 10 }) + this.parseQueue = new PQueue({ concurrency: 10 }) + const queue = this.parseQueue + for (const page of this.option.workRoute.selectedPages.val) { queue.add(async () => { + // 检查队列是否已被清空(取消解析) + if (queue !== this.parseQueue) return if (this.totalCount.val == this.finishCount.val) return const controller = new AbortController() this.abortControllers.push(controller) const playInfo = await getPlayInfo(page.bvid, page.cid, controller) + // 再次检查是否已取消 + if (queue !== this.parseQueue) return playInfo.accept_quality = [...new Set(playInfo.dash.video.map(video => video.id))].sort((a, b) => b - a) this.allPlayInfo.val = this.allPlayInfo.val.concat({ page, @@ -132,6 +142,7 @@ export class ParseModalComp implements VanComponent { }) this.finishCount.val++ }).catch(() => { + if (queue !== this.parseQueue) return this.finishCount.val++ const badgeNotNum = !page.badge.match(/^\d+$/) this.errorList.val = this.errorList.val.concat(`${page.part}${badgeNotNum ? ` - ${page.badge}` : ''}`)