Skip to content

Commit

Permalink
merge concurrent request states
Browse files Browse the repository at this point in the history
  • Loading branch information
shuding committed Dec 26, 2021
1 parent 3e0c402 commit 67deda8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 38 deletions.
31 changes: 15 additions & 16 deletions src/use-swr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ export const useSWRHandler = <Data = any, Error = any>(
STATE_UPDATERS,
MUTATION_TS,
MUTATION_END_TS,
CONCURRENT_PROMISES,
CONCURRENT_PROMISES_TS
CONCURRENT_REQUESTS
] = SWRGlobalState.get(cache) as GlobalState

// `key` is the identifier of the SWR `data` state, `keyErr` and
Expand Down Expand Up @@ -146,8 +145,7 @@ export const useSWRHandler = <Data = any, Error = any>(

// If there is no ongoing concurrent request, or `dedupe` is not set, a
// new request should be initiated.
const shouldStartNewRequest =
isUndefined(CONCURRENT_PROMISES[key]) || !opts.dedupe
const shouldStartNewRequest = !CONCURRENT_REQUESTS[key] || !opts.dedupe

// Do unmount check for calls:
// If key has changed during the revalidation, or the component has been
Expand All @@ -159,11 +157,10 @@ export const useSWRHandler = <Data = any, Error = any>(
initialMountedRef.current

const cleanupState = () => {
// CONCURRENT_PROMISES_TS[key] might be overridden, check if it's still
// the same request before deleting.
if (CONCURRENT_PROMISES_TS[key] === startAt) {
delete CONCURRENT_PROMISES[key]
delete CONCURRENT_PROMISES_TS[key]
// Check if it's still the same request before deleting.
const requestInfo = CONCURRENT_REQUESTS[key]
if (requestInfo && requestInfo[1] === startAt) {
delete CONCURRENT_REQUESTS[key]
}
}

Expand Down Expand Up @@ -202,15 +199,14 @@ export const useSWRHandler = <Data = any, Error = any>(
}, config.loadingTimeout)
}

// Start the request and keep the timestamp.
CONCURRENT_PROMISES_TS[key] = getTimestamp()
CONCURRENT_PROMISES[key] = currentFetcher(...fnArgs)
// Start the request and save the timestamp.
CONCURRENT_REQUESTS[key] = [currentFetcher(...fnArgs), getTimestamp()]
}

// Wait until the ongoing request is done. Deduplication is also
// considered here.
startAt = CONCURRENT_PROMISES_TS[key]
newData = await CONCURRENT_PROMISES[key]
;[newData, startAt] = CONCURRENT_REQUESTS[key]
newData = await newData

if (shouldStartNewRequest) {
// If the request isn't interrupted, clean it up after the
Expand All @@ -223,8 +219,11 @@ export const useSWRHandler = <Data = any, Error = any>(
// req1------------------>res1 (current one)
// req2---------------->res2
// the request that fired later will always be kept.
// CONCURRENT_PROMISES_TS[key] maybe be `undefined` or a number
if (CONCURRENT_PROMISES_TS[key] !== startAt) {
// The timestamp maybe be `undefined` or a number
if (
!CONCURRENT_REQUESTS[key] ||
CONCURRENT_REQUESTS[key][1] !== startAt
) {
if (shouldStartNewRequest) {
if (isCurrentKeyMounted()) {
getConfig().onDiscarded(key)
Expand Down
13 changes: 3 additions & 10 deletions src/utils/broadcast-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,8 @@ export const broadcastState: Broadcaster = (
revalidate,
populateCache = true
) => {
const [
EVENT_REVALIDATORS,
STATE_UPDATERS,
,
,
CONCURRENT_PROMISES,
CONCURRENT_PROMISES_TS
] = SWRGlobalState.get(cache) as GlobalState
const [EVENT_REVALIDATORS, STATE_UPDATERS, , , CONCURRENT_REQUESTS] =
SWRGlobalState.get(cache) as GlobalState
const revalidators = EVENT_REVALIDATORS[key]
const updaters = STATE_UPDATERS[key] || []

Expand All @@ -33,8 +27,7 @@ export const broadcastState: Broadcaster = (
if (revalidate) {
// Invalidate the key by deleting the concurrent request markers so new
// requests will not be deduped.
delete CONCURRENT_PROMISES[key]
delete CONCURRENT_PROMISES_TS[key]
delete CONCURRENT_REQUESTS[key]

if (revalidators && revalidators[0]) {
return revalidators[0](revalidateEvents.MUTATE_EVENT).then(() =>
Expand Down
12 changes: 2 additions & 10 deletions src/utils/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,7 @@ export const initCache = <Data = any>(
let unmount = noop

// Update the state if it's new, or the provider has been extended.
SWRGlobalState.set(provider, [
EVENT_REVALIDATORS,
{},
{},
{},
{},
{},
mutate
])
SWRGlobalState.set(provider, [EVENT_REVALIDATORS, {}, {}, {}, {}, mutate])

// This is a new provider, we need to initialize it and setup DOM events
// listeners for `focus` and `reconnect` actions.
Expand Down Expand Up @@ -104,5 +96,5 @@ export const initCache = <Data = any>(
return [provider, mutate, unmount]
}

return [provider, (SWRGlobalState.get(provider) as GlobalState)[6]]
return [provider, (SWRGlobalState.get(provider) as GlobalState)[5]]
}
3 changes: 1 addition & 2 deletions src/utils/global-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ export type GlobalState = [
Record<string, StateUpdateCallback[]>, // STATE_UPDATERS
Record<string, number>, // MUTATION_TS
Record<string, number>, // MUTATION_END_TS
Record<string, any>, // CONCURRENT_PROMISES
Record<string, number>, // CONCURRENT_PROMISES_TS
Record<string, [any, number]>, // CONCURRENT_REQUESTS: [data, ts]
ScopedMutator // Mutator
]

Expand Down

0 comments on commit 67deda8

Please sign in to comment.