When two useAsyncData with same key refresh at same time, only one of them updates.
See original GitHub issueEnvironment
- Operating System: Darwin
- Node Version: v14.18.2
- Nuxt Version: 3.0.0-rc.3
- Package Manager: npm@6.14.17
- Builder: vite
- User Config: typescript, publicRuntimeConfig, buildModules, alias, vite
- Runtime Modules: -
- Build Modules: @pinia/nuxt@0.1.9
Reproduction
Simple demostrate
let i = 0;
const fetch = () => {
console.log('load');
return new Promise((resolve) => setTimeout(() => resolve(i++), 100));
};
const getData = () => useAsyncData('requestKey', fetch);
const a = await getData();
const b = await getData();
const refresh = () => {
a.refresh();
b.refresh();
};
Full https://stackblitz.com/edit/github-ymf7zt?file=app.vue Click the refresh button
Describe the bug
The cache of useAsyncData errornously cache the part that apply change to data container. Results in the second use refresh completely ignored.
These lines are not supposed to be cached, because the asyncData
is not guranteed to be the same instance even key is the same.
Additional context
My temporay patch
diff --git a/node_modules/nuxt/dist/app/composables/asyncData.mjs b/node_modules/nuxt/dist/app/composables/asyncData.mjs index 3b49030..eb29161 100644 --- a/node_modules/nuxt/dist/app/composables/asyncData.mjs +++ b/node_modules/nuxt/dist/app/composables/asyncData.mjs @@ -35,15 +35,21 @@ export function useAsyncData(key, handler, options = {}) { pending: ref(!useInitialCache()), error: ref(nuxt.payload._errors[key] ?? null) }; + let localDataPromise asyncData.refresh = (opts = {}) => { + let dataPromise if (nuxt._asyncDataPromises[key]) { - return nuxt._asyncDataPromises[key]; + dataPromise = nuxt._asyncDataPromises[key]; } if (opts._initial && useInitialCache()) { return nuxt.payload.data[key]; } asyncData.pending.value = true; - nuxt._asyncDataPromises[key] = Promise.resolve(handler(nuxt)).then((result) => { + if (dataPromise == null) { + dataPromise = Promise.resolve(handler(nuxt)) + nuxt._asyncDataPromises[key] = dataPromise + } + localDataPromise = dataPromise.then((result) => { if (options.transform) { result = options.transform(result); } @@ -63,7 +69,7 @@ export function useAsyncData(key, handler, options = {}) { } delete nuxt._asyncDataPromises[key]; }); - return nuxt._asyncDataPromises[key]; + return localDataPromise }; const initialFetch = () => asyncData.refresh({ _initial: true }); const fetchOnServer = options.server !== false && nuxt.payload.serverRendered; @@ -91,7 +97,7 @@ export function useAsyncData(key, handler, options = {}) { onUnmounted(off); } } - const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => asyncData); + const asyncDataPromise = Promise.resolve(localDataPromise).catch(() => {}).then(() => asyncData); Object.assign(asyncDataPromise, asyncData); return asyncDataPromise; }
Cache the handler(nuxt)
but always apply the rest
Logs
No response
Issue Analytics
- State:
- Created a year ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
How to refresh the data obtained by Async Data() in NuxtJs?
In pure Vue, I would write an ajax method to update the data from the server after removal. Usually this method is the...
Read more >Understanding Difference Between Asyncdata Fetch Nuxt
Nuxt provides two useful hooks for fetching data: AsyncData and Fetch. They're available at different times in the Nuxt lifecycle, ...
Read more >Nuxt 3 | Data fetching | useAsyncData | useFetch - YouTube
Hi all,Thanks a lot guys for voting in the poll that I ran last week. It was super helpful.As per the majority, here...
Read more >Why Use Nuxt JS 3 Beta?! (Vue.js 3 With Nuxt Tutorial!!)
Nuxt JS 3 Beta has just been released? Should you use it in your next project? Does it hold up to the hype?...
Read more >Async data made simple with React Query - Hey! I'm Tyler
A library of custom hooks that solves async data fetching and caching within ... key”, is to pass it an array of strings....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
It seems this issue need to be revisited due to change in RC9.
Due to following change. https://github.com/nuxt/framework/pull/7055 This issue seems to be no longer reproducible.
I just came across this behaviour, because my second call to
refresh()
wasn’t fetching new data. I thought I was usinguseAsyncData
incorrectly, but after looking through it’s implementation I realized that’s how it works.I was able to fix this by making sure to call
await
onrefresh()
before calling it a second time, but I think the default implementation should be to cancel the first promise when the data gets refreshed. There’s aTODO
about this in the code foruseAsyncData
here. Given thatuseAsyncData
is one of the core functions of the framework shouldn’t this get prioritized?Here’s my (local) fix: