Skip to content

Commit e964498

Browse files
committed
Only reset cache timers when subscription counts hit 0
1 parent 4cea2bf commit e964498

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

packages/toolkit/src/query/core/buildMiddleware/cacheCollection.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ import type {
1111

1212
export type ReferenceCacheCollection = never
1313

14+
function isObjectEmpty(obj: Record<any, any>) {
15+
// Apparently a for..in loop is faster than `Object.keys()` here:
16+
// https://stackoverflow.com/a/59787784/62937
17+
for (let k in obj) {
18+
// If there is at least one key, it's not empty
19+
return false
20+
}
21+
return true
22+
}
23+
1424
declare module '../../endpointDefinitions' {
1525
interface QueryExtraOptions<
1626
TagTypes extends string,
@@ -38,6 +48,15 @@ export const THIRTY_TWO_BIT_MAX_TIMER_SECONDS = 2_147_483_647 / 1_000 - 1
3848
export const build: SubMiddlewareBuilder = ({ reducerPath, api, context }) => {
3949
const { removeQueryResult, unsubscribeQueryResult } = api.internalActions
4050

51+
function anySubscriptionsRemainingForKey(
52+
queryCacheKey: string,
53+
api: SubMiddlewareApi
54+
) {
55+
const subscriptions =
56+
api.getState()[reducerPath].subscriptions[queryCacheKey]
57+
return !!subscriptions && !isObjectEmpty(subscriptions)
58+
}
59+
4160
return (mwApi) => {
4261
const currentRemovalTimeouts: QueryStateMeta<TimeoutId> = {}
4362

@@ -103,18 +122,18 @@ export const build: SubMiddlewareBuilder = ({ reducerPath, api, context }) => {
103122
Math.min(keepUnusedDataFor, THIRTY_TWO_BIT_MAX_TIMER_SECONDS)
104123
)
105124

106-
const currentTimeout = currentRemovalTimeouts[queryCacheKey]
107-
if (currentTimeout) {
108-
clearTimeout(currentTimeout)
109-
}
110-
currentRemovalTimeouts[queryCacheKey] = setTimeout(() => {
111-
const subscriptions =
112-
api.getState()[reducerPath].subscriptions[queryCacheKey]
113-
if (!subscriptions || Object.keys(subscriptions).length === 0) {
114-
api.dispatch(removeQueryResult({ queryCacheKey }))
125+
if (!anySubscriptionsRemainingForKey(queryCacheKey, api)) {
126+
const currentTimeout = currentRemovalTimeouts[queryCacheKey]
127+
if (currentTimeout) {
128+
clearTimeout(currentTimeout)
115129
}
116-
delete currentRemovalTimeouts![queryCacheKey]
117-
}, finalKeepUnusedDataFor * 1000)
130+
currentRemovalTimeouts[queryCacheKey] = setTimeout(() => {
131+
if (!anySubscriptionsRemainingForKey(queryCacheKey, api)) {
132+
api.dispatch(removeQueryResult({ queryCacheKey }))
133+
}
134+
delete currentRemovalTimeouts![queryCacheKey]
135+
}, finalKeepUnusedDataFor * 1000)
136+
}
118137
}
119138
}
120139
}

0 commit comments

Comments
 (0)