深度解析微信小程序数据预拉取API调用的问题与使用方法


了解到通过配置数据预拉取可以在更早的生命周期调用网络请求以提升首屏数据的渲染速度,但通过官方文档和网上各种文章解析,都没有把API给解释明白且社区存在大量反馈问题,通过深入的了解和调试,故写下本解析文章。本文内容全网首发,转载请注明作者:Zeekin。

官方文档说明

首先配置预拉取地址信息和在开发者工具开启数据预拉取功能这些基础问题就不说了,网上看到存惑的大概就是两个API的使用,以下是小程序官方文档的解释:

wx.getBackgroundFetchData(object object)

拉取 backgroundFetch 客户端缓存数据。 当调用接口时,若当次请求未结束,会先返回本地的旧数据(之前打开小程序时请求的),如果本地没有旧数据,安卓上会返回fail,不会等待请求完成,iOS上会返回success但fetchedData为空,也不会等待请求完成。建议和 wx.onBackgroundFetchData 配合使用。

wx.onBackgroundFetchData(function listener)

监听收到 backgroundFetch 数据事件。如果监听时请求已经完成,则事件不会触发。建议和 wx.getBackgroundFetchData 配合使用

第一次看完这两个API的解释实在是云里雾里,果不其然,打开社区一看都是铺天盖地的问题,证明大家普遍都没有理解明白。

原理与问题分析

言归正传,先来解释一下这两个API到底是用来干什么的。

一个非常重要的前提:这两个API都是用于获取数据的,跟发起网络请求无关,也就是说无论在哪调用都不会影响网络请求的时机,不管你有没有调用这个API,只要你配置了数据预拉取的地址,启动小程序时就会进行接口网络请求。

wx.getBackgroundFetchData

这个 API 用于拉取最新数据/缓存数据。如果调用这个API的时候网络请求还没有完成,有缓存的情况下会立即返回本地缓存的旧数据,没有缓存时IOS返回空,安卓返回fail,无论什么情况不会等待请求完成。

”第一次启动数据为空,第二次才有数据“

这是因为首次调用这个API的时候网络请求还没有完成且本地也没有缓存,而接口也不会等到请求完成才返回数据,所以返回数据直接就是为空

第二次打开的时候,虽然调用API时网络请求还是没有完成,但因为第一次打开的时候已经请求了接口,本地有缓存数据,所以就直接返回了缓存数据

”一直取缓存数据,无法获取更新的数据“

参考上面的情况,因为本地有缓存且调用这个API的时候网络请求还没有完成,所以返回的是上次的缓存,通过对比时间戳可以说明这个问题。(一直拉的是缓存的情况可能存在设备兼容差异,IOS没有复现这个情况)

所以单独使用这个API的话会存在以上问题,除非你是在非小程序启动的时候需要调取数据,也就是确保你在网络请求完成后调用这个API,这个情况是可以正常使用的,但用这个API基本都是为了优化首屏的数据渲染时间,所以也不太合理。

wx.onBackgroundFetchData

这个API用于监听数据。只有在调用这个API的时网络请求还没有完成才会触发,然后返回请求的数据。

”返回不了数据,只有getBackgroundFetchData有数据”

在调用API时,网络请求已经完成了,导致事件不会触发。这种情况大概率是因为调用API的时机晚了,我们可以用定时器模拟这个情况,以下输出结果就是怎么样都获取不到数据。

setTimeout(()=>{
	wx.onBackgroundFetchData((res) => {
	 console.log('调用onBackgroundFetchData丨zeekin.cn测试',JSON.parse(res.fetchedData));
	})
},3000)

结论与使用方法

这两个API名称有点长,为了更清晰的表述,onBackgroundFetchData 下称onData,getBackgroundFetchData 下称getData。

从整个程序的启动生命周期来讲,假如我们需要在onLaunch就拉取数据,首次启动程序是通过 onData 来获取数据,因为网络请求没有那么快,getData 基本是获取不到数据的。在首次访问后本地就有了缓存,在第二次启动程序的时候因为网络请求没有那么快,getData大概率会直接拉取到缓存,onData 会拉取到本次网络请求最新的数据,也就是两个API同时拉取到数据,一个新一个旧,具体如下图的时间戳。

既然一个新一个旧,那么要两个API都使用的意义是什么?这是因为假如你的网络接口出现了问题或者非常慢,getData可以立即返回上次的缓存的数据,这样才不会影响你的首屏渲染。如果接口请求没有问题,那么就可以通过onData 拿到最新的数据。也就是说把业务处理写在两个API之后,这样可以保证及时拉取数据也可以保证数据是最新的。

在社区中官方回复的getData可能拉到新的也可能旧的,可能大多数人还是难以理解这句话,通过本文就明白了,可能存在调用时机/网络接口速度的影响让getData也可能可以获取到新数据,但还是需要配合onData使用才能保证达到稳定的情况。

总结

虽然官方给出了同时使用两个API的案例,但很多人无法理解,甚至通过官方回复还是无法明白原理,并且网上也查不到相关的说明文章,最后因为无法理解两个API的具体使用细节最终放弃使用,这实在是很可惜。 时至今日还是能看到相关的疑问贴,所以写下这篇文章,希望对你的业务开发有帮助。


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注