@@ -425,6 +425,7 @@ public final class Query<TData: Sendable, TKey: QueryKey>: AnyQuery {
425425 }
426426
427427 /// Cancel any ongoing fetch operation
428+ /// Note: This should only be called when explicitly requested or when no observers remain
428429 public func cancel( ) {
429430 fetchTask? . cancel ( )
430431 fetchTask = nil
@@ -463,15 +464,15 @@ public final class Query<TData: Sendable, TKey: QueryKey>: AnyQuery {
463464 observers. removeAll { $0. id == observer. id }
464465
465466 if observers. isEmpty {
466- // Cancel ongoing fetch if no observers and allow revert
467- if let revertState {
467+ // If there's a revert state and we're currently fetching, revert to previous state
468+ if let revertState, state . fetchStatus == . fetching {
468469 setState ( revertState)
469470 self . revertState = nil
470471 }
471472
472- // If the query is still fetching, let it continue to cache the result
473- // Only cancel if we can safely revert
474- if fetchTask != nil , revertState != nil {
473+ // Cancel any ongoing fetch when no observers remain
474+ // This prevents unnecessary network usage when no one is listening for the result
475+ if fetchTask != nil {
475476 fetchTask? . cancel ( )
476477 fetchTask = nil
477478 }
@@ -527,13 +528,19 @@ public final class Query<TData: Sendable, TKey: QueryKey>: AnyQuery {
527528 // MARK: - Fetch Implementation
528529
529530 /// Internal fetch implementation that executes the query function
531+ /// Implements request deduplication - if a fetch is already in progress,
532+ /// returns the existing promise instead of starting a new one
530533 public func internalFetch( ) async throws -> TData {
534+ // If we're already fetching, return the existing promise
535+ // This implements request deduplication similar to TanStack Query
536+ if let existingTask = fetchTask, state. fetchStatus == . fetching {
537+ // Return the existing task's value - all callers share the same request
538+ return try await existingTask. value
539+ }
540+
531541 // Store current state to revert if fetch is cancelled
532542 revertState = state
533543
534- // Cancel any existing fetch
535- fetchTask? . cancel ( )
536-
537544 // Update state to fetching
538545 dispatch ( . fetch( meta: nil ) )
539546
0 commit comments