From d1646d1ad07c914b2378813455ce42e84fa6c8f3 Mon Sep 17 00:00:00 2001 From: liujiayii Date: Thu, 28 May 2026 15:23:23 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(interceptor):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E8=83=BD=E5=8A=9B=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=BC=82=E6=AD=A5=E6=8B=A6=E6=88=AA=E5=92=8C=E6=8B=A6?= =?UTF-8?q?=E6=88=AA=E9=98=BB=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增了拦截器同步/异步返回false时阻断API调用的能力,同时支持异步拦截器修改传入参数 添加了完整的拦截器单元测试用例覆盖各类场景 重构了拦截器队列执行逻辑,统一同步异步处理流程 --- .../__tests__/helpers/interceptor.spec.ts | 65 +++++++++++++++++++ packages/uni-api/src/helpers/interceptor.ts | 28 ++++++-- 2 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 packages/uni-api/__tests__/helpers/interceptor.spec.ts diff --git a/packages/uni-api/__tests__/helpers/interceptor.spec.ts b/packages/uni-api/__tests__/helpers/interceptor.spec.ts new file mode 100644 index 0000000000..c01d9b65c5 --- /dev/null +++ b/packages/uni-api/__tests__/helpers/interceptor.spec.ts @@ -0,0 +1,65 @@ +import { + globalInterceptors, + invokeApi, + scopedInterceptors, +} from '../../src/helpers/interceptor' + +function resetInterceptors() { + Object.keys(globalInterceptors).forEach((key) => { + delete globalInterceptors[key as keyof typeof globalInterceptors] + }) + Object.keys(scopedInterceptors).forEach((key) => { + delete scopedInterceptors[key] + }) +} + +describe('interceptor', () => { + afterEach(() => { + resetInterceptors() + }) + + test('blocks api invocation when invoke returns false synchronously', () => { + const api = jest.fn() + globalInterceptors.invoke = [ + () => { + return false + }, + ] + + const res = invokeApi('test', api, {}, []) + + expect(res).toBeUndefined() + expect(api).not.toHaveBeenCalled() + }) + + test('blocks api invocation when invoke resolves false asynchronously', async () => { + const api = jest.fn() + globalInterceptors.invoke = [ + () => { + return Promise.resolve(false) + }, + ] + + invokeApi('test', api, {}, []) + await new Promise((resolve) => setTimeout(resolve, 0)) + + expect(api).not.toHaveBeenCalled() + }) + + test('passes resolved options to api invocation', async () => { + const api = jest.fn((options) => options) + const options = { url: '/old' } + const resolvedOptions = { url: '/new' } + globalInterceptors.invoke = [ + () => { + return Promise.resolve(resolvedOptions) + }, + ] + + const res = await invokeApi('test', api, options, []) + + expect(res).toBe(resolvedOptions) + expect(api).toHaveBeenCalledTimes(1) + expect(api).toHaveBeenCalledWith(resolvedOptions) + }) +}) diff --git a/packages/uni-api/src/helpers/interceptor.ts b/packages/uni-api/src/helpers/interceptor.ts index d31543921a..3496c61360 100644 --- a/packages/uni-api/src/helpers/interceptor.ts +++ b/packages/uni-api/src/helpers/interceptor.ts @@ -20,9 +20,24 @@ export type Interceptors = { [P in HOOKS]?: Function[] } export const globalInterceptors: Interceptors = {} export const scopedInterceptors: { [key: string]: Interceptors } = {} +const API_INVOKE_ABORT = { + then() {}, + catch() {}, +} as Promise + +function resolveHookResult(res: unknown, data?: unknown) { + return res === false ? API_INVOKE_ABORT : res || data +} + function wrapperHook(hook: Function, params?: Record) { return function (data: unknown) { - return hook(data, params) || data + const res = hook(data, params) + if (isPromise(res)) { + return Promise.resolve(res).then((res) => { + return resolveHookResult(res, data) + }) + } + return resolveHookResult(res, data) } } @@ -35,17 +50,16 @@ function queue( for (let i = 0; i < hooks.length; i++) { const hook = hooks[i] if (promise) { - promise = Promise.resolve(wrapperHook(hook, params)) + promise = promise.then(wrapperHook(hook, params)) } else { const res = hook(data, params) if (isPromise(res)) { - promise = Promise.resolve(res) + promise = Promise.resolve(res).then((res) => { + return resolveHookResult(res) + }) } if (res === false) { - return { - then() {}, - catch() {}, - } as Promise + return API_INVOKE_ABORT } } } From 997c646efaa3358de261247338f845b9873d0d47 Mon Sep 17 00:00:00 2001 From: liujiayii Date: Thu, 28 May 2026 16:47:52 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(playground):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E7=A4=BA=E4=BE=8B=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/playground/assets/src/pages.json | 3 + .../assets/src/pages/index/index.vue | 1 + .../src/pages/interceptor/interceptor.vue | 237 ++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 packages/playground/assets/src/pages/interceptor/interceptor.vue diff --git a/packages/playground/assets/src/pages.json b/packages/playground/assets/src/pages.json index 55d2e21fc9..1fc69eddbf 100644 --- a/packages/playground/assets/src/pages.json +++ b/packages/playground/assets/src/pages.json @@ -2,6 +2,9 @@ "pages": [ { "path": "pages/index/index" + }, + { + "path": "pages/interceptor/interceptor" } ], "subPackages": [ diff --git a/packages/playground/assets/src/pages/index/index.vue b/packages/playground/assets/src/pages/index/index.vue index 19fe87ba48..aeaae7c802 100644 --- a/packages/playground/assets/src/pages/index/index.vue +++ b/packages/playground/assets/src/pages/index/index.vue @@ -1,6 +1,7 @@