From 55ad567849db3d84b24744d5faf076d42e5fc1d5 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 20 May 2022 10:48:42 +0000 Subject: [PATCH 1/4] fix: Temporary fix for https://github.com/nuxt/framework/issues/4758 --- packages/nuxt/src/app/composables/asyncData.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 40ab34494a1..7067696f21a 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -113,10 +113,14 @@ export function useAsyncData< } asyncData.data.value = result asyncData.error.value = null + + return asyncData; }) .catch((error: any) => { asyncData.error.value = error asyncData.data.value = unref(options.default()) + + return asyncData; }) .finally(() => { asyncData.pending.value = false @@ -166,7 +170,7 @@ export function useAsyncData< } // Allow directly awaiting on asyncData - const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => asyncData) as AsyncData + const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(x => x) as AsyncData Object.assign(asyncDataPromise, asyncData) return asyncDataPromise as AsyncData, PickKeys>, DataE> From 637868edf346db825df09d4aeffe93f8647509df Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 20 May 2022 14:33:11 +0100 Subject: [PATCH 2/4] Apply suggestions from code review --- packages/nuxt/src/app/composables/asyncData.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 7067696f21a..973b43d0f1a 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -114,13 +114,13 @@ export function useAsyncData< asyncData.data.value = result asyncData.error.value = null - return asyncData; + return asyncData }) .catch((error: any) => { asyncData.error.value = error asyncData.data.value = unref(options.default()) - return asyncData; + return asyncData }) .finally(() => { asyncData.pending.value = false @@ -170,7 +170,7 @@ export function useAsyncData< } // Allow directly awaiting on asyncData - const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(x => x) as AsyncData + const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]) as AsyncData Object.assign(asyncDataPromise, asyncData) return asyncDataPromise as AsyncData, PickKeys>, DataE> From 5c2230e3babde3c5607fd799a23e9e1afe5d9c14 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 May 2022 16:33:51 +0100 Subject: [PATCH 3/4] fix: share pending async data in nuxt --- .../nuxt/src/app/composables/asyncData.ts | 22 ++++++++++++++----- packages/nuxt/src/app/nuxt.ts | 3 +++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 973b43d0f1a..a26f4460b58 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -85,12 +85,20 @@ export function useAsyncData< const useInitialCache = () => options.initialCache && nuxt.payload.data[key] !== undefined - const asyncData = { + let asyncData = { data: wrapInRef(nuxt.payload.data[key] ?? options.default()), pending: ref(!useInitialCache()), error: ref(nuxt.payload._errors[key] ?? null) } as AsyncData + // If this query is pending, grab async data from store + // Otherwise, set our async data + if (nuxt._asyncDataPromises[key]) { + asyncData = nuxt._pendingAsyncData[key] + } else { + nuxt._pendingAsyncData[key] = asyncData + } + asyncData.refresh = (opts = {}) => { // Avoid fetching same key more than once at a time if (nuxt._asyncDataPromises[key]) { @@ -98,6 +106,10 @@ export function useAsyncData< } // Avoid fetching same key that is already fetched if (opts._initial && useInitialCache()) { + + // Prevent memory leak, no promise to resolve so key is never deleted + delete nuxt._pendingAsyncData[key] + return nuxt.payload.data[key] } asyncData.pending.value = true @@ -113,14 +125,10 @@ export function useAsyncData< } asyncData.data.value = result asyncData.error.value = null - - return asyncData }) .catch((error: any) => { asyncData.error.value = error asyncData.data.value = unref(options.default()) - - return asyncData }) .finally(() => { asyncData.pending.value = false @@ -129,6 +137,7 @@ export function useAsyncData< nuxt.payload._errors[key] = true } delete nuxt._asyncDataPromises[key] + delete nuxt._pendingAsyncData[key] }) return nuxt._asyncDataPromises[key] } @@ -170,7 +179,8 @@ export function useAsyncData< } // Allow directly awaiting on asyncData - const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]) as AsyncData + const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => asyncData) as AsyncData + Object.assign(asyncDataPromise, asyncData) return asyncDataPromise as AsyncData, PickKeys>, DataE> diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index 65d50a560b0..ff197e63d1b 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -5,6 +5,7 @@ import { createHooks, Hookable } from 'hookable' import type { RuntimeConfig } from '@nuxt/schema' import { getContext } from 'unctx' import { legacyPlugin, LegacyContext } from './compat/legacy-app' +import { AsyncData } from './composables/asyncData' const nuxtAppCtx = getContext('nuxt-app') @@ -46,6 +47,7 @@ interface _NuxtApp { [key: string]: any _asyncDataPromises?: Record> + _pendingAsyncData?: Record> _legacyContext?: LegacyContext ssrContext?: Record & { @@ -91,6 +93,7 @@ export function createNuxtApp (options: CreateOptions) { }), isHydrating: process.client, _asyncDataPromises: {}, + _pendingAsyncData: {}, ...options } as any as NuxtApp From 5a55582d8e4ddffb91946135acee56a8dd63d2b9 Mon Sep 17 00:00:00 2001 From: Your Name <105918055+cherrymarker@users.noreply.github.com> Date: Fri, 20 May 2022 18:13:32 +0100 Subject: [PATCH 4/4] fix: linting issues --- packages/nuxt/src/app/composables/asyncData.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index a26f4460b58..1bd3d2133c2 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -106,7 +106,6 @@ export function useAsyncData< } // Avoid fetching same key that is already fetched if (opts._initial && useInitialCache()) { - // Prevent memory leak, no promise to resolve so key is never deleted delete nuxt._pendingAsyncData[key] @@ -180,7 +179,7 @@ export function useAsyncData< // Allow directly awaiting on asyncData const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => asyncData) as AsyncData - + Object.assign(asyncDataPromise, asyncData) return asyncDataPromise as AsyncData, PickKeys>, DataE>