在Angular与Apollo GraphQL中实现每次请求获取全新结果的无缓存策略
问题场景
我们需要每次请求都获取一个动态变化的值(比如nonce),但在Apollo Angular客户端中遇到了问题:单次请求能正常拿到新值,但并发发起多次相同查询时,所有请求返回的nonce完全一致;只有等第一个请求完成后再发第二个,才能拿到不同的值。
已尝试的方案
- 使用带
no-cache策略的watchQuery:
this.apollo.watchQuery<any>({query: NONCE_QUERY, fetchPolicy: 'no-cache'}) .valueChanges .pipe(first()) .subscribe(response => console.log(response.data.nonce));
- 替换为
query方法,结果完全一致:
this.apollo.query<any>({query: NONCE_QUERY, fetchPolicy: 'no-cache'}) .subscribe(response => console.log(response.data.nonce));
两种方式都无法解决并发请求返回相同值的问题。
当前Apollo配置
{ provide: APOLLO_OPTIONS, useFactory: (httpLink: HttpLink): ApolloClientOptions<any> => { return { cache: new InMemoryCache(), link: httpLink.create({ uri: 'URL', withCredentials: true, }), defaultOptions: { query: { fetchPolicy: 'no-cache' } } }; }, deps: [HttpLink], }
解决方案
问题根源是Apollo默认会对**相同查询(相同的query和变量组合)**进行请求去重(deduplication),并发请求时会复用同一个网络请求,导致返回相同结果。要关闭这个行为,只需在请求配置中添加context: { deduplicate: false }:
方式1:单个请求配置
// 使用watchQuery this.apollo.watchQuery<any>({ query: NONCE_QUERY, fetchPolicy: 'no-cache', context: { deduplicate: false } // 关键配置 }) .valueChanges .pipe(first()) .subscribe(response => console.log(response.data.nonce)); // 使用query this.apollo.query<any>({ query: NONCE_QUERY, fetchPolicy: 'no-cache', context: { deduplicate: false } // 关键配置 }) .subscribe(response => console.log(response.data.nonce));
方式2:全局默认配置
如果所有这类动态查询都需要关闭去重,可以在Apollo全局配置中添加默认context:
{ provide: APOLLO_OPTIONS, useFactory: (httpLink: HttpLink): ApolloClientOptions<any> => { return { cache: new InMemoryCache(), link: httpLink.create({ uri: 'URL', withCredentials: true, }), defaultOptions: { query: { fetchPolicy: 'no-cache', context: { deduplicate: false } // 全局关闭去重 } } }; }, deps: [HttpLink], }
这样配置后,即使并发发起相同查询,Apollo也会每次都发送独立的网络请求,从而获取到每次都不同的nonce值。
内容的提问来源于stack exchange,提问作者lampshade
相关产品推荐
相关产品推荐

