ApolloGraphQL Angular客户端中loading属性的用法探究
Apollo Angular 相关问题解答
Hey there, let's walk through your three questions about that Apollo Angular code step by step:
1. 为何使用this.loading = loading而非直接赋值为this.loading = false?
Apollo的watchQuery返回的可不是只发一次值的普通Observable——它是一个多值流。举个例子:
- 当你首次发起请求且缓存里没有数据时,它会先发射一个
{ loading: true, data: undefined }的状态,告诉你"我正在加载中"; - 等服务器返回数据后,再发射
{ loading: false, data: ... }的结果; - 甚至之后如果缓存里的数据有更新(比如其他组件修改了同一份数据),它还会再次发射新的结果,这时候
loading也可能根据情况变化。
如果直接硬写this.loading = false,你就会完全忽略掉初始的加载状态,用户界面上根本看不到"加载中"的提示,体验会很差。跟着传入的loading参数赋值,才能准确同步Apollo当前的请求状态。
2. 单次调用ngOnInit()时,.subscribe()中的闭包可能被调用多少次?
这个次数没有固定答案,得看你的Apollo配置和数据的生命周期:
- 最少1次:如果缓存里已经有你要的数据,且用的是默认的
cache-first策略,订阅后会直接发射{ loading: false, data: ... },闭包只执行一次; - 最少2次:如果用
network-only或者cache-and-network策略,第一次会发射loading: true,等服务器返回数据后再发射loading: false带数据,闭包执行两次; - N次:只要组件还在订阅这个Observable,每当缓存里的对应数据被更新(比如通过
mutate修改后触发缓存同步),闭包就会再次执行,发射最新的data和对应的loading状态。
3. loading字段是否可能为真值?
当然有可能!很多场景下都会出现loading: true:
- 当你使用
network-only策略时,订阅后会先收到loading: true,直到服务器返回数据才变成false; - 用
cache-and-network策略时,即使缓存有数据,Apollo也会偷偷去服务器拉取最新数据,这时候也可能会发射一次loading: true; - 当你主动调用
refetch()方法重新请求数据时,也会再次触发loading: true的状态。
你当前的代码只收到loading: false,大概率是因为缓存里已经有现成的数据了,Apollo直接返回了缓存结果,跳过了加载状态。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

