From 457509a67f4bb5a173c7889583206b4c81152c6a Mon Sep 17 00:00:00 2001 From: Young Date: Thu, 6 Oct 2022 07:55:32 +0800 Subject: [PATCH] fix(useFetch): fix incorrect `chainCallbacks` behavior (#2231) --- packages/core/useFetch/index.test.ts | 42 ++++++++++++++++++++++++++++ packages/core/useFetch/index.ts | 6 ++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/core/useFetch/index.test.ts b/packages/core/useFetch/index.test.ts index 8567b335957..0ce62112940 100644 --- a/packages/core/useFetch/index.test.ts +++ b/packages/core/useFetch/index.test.ts @@ -337,6 +337,48 @@ describe('useFetch', () => { }) }) + test('async chained beforeFetch and afterFetch should be executed in order', async () => { + const sleep = (delay: number) => new Promise(resolve => setTimeout(resolve, delay)) + + const useMyFetch = createFetch({ + baseUrl: 'https://example.com', + options: { + async beforeFetch({ options }) { + await sleep(50) + options.headers = { ...options.headers, title: 'Hunter X Hunter' } + return { options } + }, + async afterFetch(ctx) { + await sleep(50) + ctx.data.message = 'Hunter X Hunter' + return ctx + }, + }, + }) + + const { data } = await useMyFetch( + 'test?json', + { method: 'GET' }, + { + async beforeFetch({ options }) { + await Promise.resolve() + options.headers = { ...options.headers, title: 'Hello, VueUse' } + return { options } + }, + async afterFetch(ctx) { + await Promise.resolve() + ctx.data.message = 'Hello, VueUse' + return ctx + }, + }, + ).json() + + await retry(() => { + expect(fetchSpyHeaders()).toMatchObject({ title: 'Hello, VueUse' }) + expect(data.value).toEqual(expect.objectContaining({ message: 'Hello, VueUse' })) + }) + }) + test('should run the onFetchError function', async () => { const { data, statusCode } = useFetch('https://example.com?status=400&json', { onFetchError(ctx) { diff --git a/packages/core/useFetch/index.ts b/packages/core/useFetch/index.ts index 82397fc2ea3..3d1f701630e 100644 --- a/packages/core/useFetch/index.ts +++ b/packages/core/useFetch/index.ts @@ -215,11 +215,11 @@ function headersToObject(headers: HeadersInit | undefined) { } function chainCallbacks(...callbacks: (((ctx: T) => void | Partial | Promise>) | undefined)[]) { - return (ctx: T) => { - callbacks.forEach(async (callback) => { + return async (ctx: T) => { + await callbacks.reduce((prevCallback, callback) => prevCallback.then(async () => { if (callback) ctx = { ...ctx, ...(await callback(ctx)) } - }) + }), Promise.resolve()) return ctx } }