这篇文章通过一个实际工作的例子说明“依赖注入”的一个具体作用,欢迎大家点评。
基本背景
微信小程序启动时会生成一个 App 对象,开发者在各个页面中可以通过 getApp()
方法来调用到它,所以它有共享数据的作用。小程序的启动从 App.onLaunch()
函数开始,在这个函数运行结束以后,getApp()
才可以顺利调用。
小程序提供的 HTTP 网络接口 wx.request
承接了 HTTP 的无状态特性,我们为了提供验证 API 和重试的功能,在这个网络接口的基础上外套了一层,做了一个有状态网络工具。为了让小程序的整个生命周期都能共享一次验证得到的密钥,我们把这个工具做成了单例,在一个 JavaScript 文件里暴露一个 get
接口来获取这个实例。
我们把有状态网络工具写进了 App 对象中,让它作为一个成员存在。这样各页面,各 JavaScript 函数都可以通过 getApp().statefulNetworkUtility
来获取到这个关键的网络工具。
尽管我们给 wx.request
外包了一层,但发请求时候的参数仍然很多:
- URL
- 请求体数据
- 请求头部
- 成功回调函数
- 失败回调函数
于是我们再在调用网络工具的代码外面增加一层,放在 api-tools.js
文件中,这之后客户端就可以使用比较轻量化的函数来进行网络请求了,比如
apiTool.getLatestNews(successCallback, failureCallback)
问题描述
问题来源的需求是想在启动时向后端发送一些状态数据,于是要在 App.onLaunch()
运行的时候调用:apiTool.sendStatus()
. 函数签名如下。
function sendStatus(data, successCallback, failureCallback)
apiTool
的内部需要通过 getApp().statefulNetworkUtility
来获得网络工具,然而在 App 对象生成的时候,getApp()
调用是失败的,这时候我们怎么办?
解决办法
由于有状态网络工具是 App 对象的一个成员,而在 App.onLaunch()
运行之前,所有成员会先初始化,所以在 onLaunch()
运行的时候,内存中是有一个好用的网络工具的,工具的存在不是问题。那么我们如何用到它呢?这个时候就用到了标题所说的“依赖注入”。我们改造一下 apiTool.sendStatus()
,参数中增加一个指向网络工具的引用。现在的函数签名变成如下所示。
function sendStatus(data, successCallback, failureCallback, networkUtility)
然后在 onLaunch()
函数中通过 apiTool.sendStatus(data, successCallback, failureCallback, this.statefulNetworkUtility)
来使用。