@@ -35,11 +35,14 @@ public final class GraphQLQueryWatcher<Query: GraphQLQuery>: Cancellable, Apollo
3535 fetch ( cachePolicy: . fetchIgnoringCacheData)
3636 }
3737
38+ // Watchers always call result handlers on the main queue.
39+ private let callbackQueue : DispatchQueue = . main
40+
3841 func fetch( cachePolicy: CachePolicy ) {
3942 // Cancel anything already in flight before starting a new fetch
4043 fetching? . cancel ( )
41- fetching = client? . fetch ( query: query, cachePolicy: cachePolicy, context: & context, queue: . main ) { [ weak self] result in
42- guard let ` self` = self else { return }
44+ fetching = client? . fetch ( query: query, cachePolicy: cachePolicy, context: & context, queue: callbackQueue ) { [ weak self] result in
45+ guard let self = self else { return }
4346
4447 switch result {
4548 case . success( let graphQLResult) :
@@ -66,7 +69,20 @@ public final class GraphQLQueryWatcher<Query: GraphQLQuery>: Cancellable, Apollo
6669 guard let dependentKeys = dependentKeys else { return }
6770
6871 if !dependentKeys. isDisjoint ( with: changedKeys) {
69- fetch ( cachePolicy: . returnCacheDataElseFetch)
72+ // First, attempt to reload the query from the cache directly, in order not to interrupt any in-flight server-side fetch.
73+ store. load ( query: query) { [ weak self] result in
74+ guard let self = self else { return }
75+
76+ switch result {
77+ case . success:
78+ self . callbackQueue. async { [ weak self] in
79+ self ? . resultHandler ( result)
80+ }
81+ case . failure:
82+ // If the cache fetch is not successful, for instance if the data is missing, refresh from the server.
83+ self . fetch ( cachePolicy: . fetchIgnoringCacheData)
84+ }
85+ }
7086 }
7187 }
7288}
0 commit comments