前言
在之前的文章Moya+PromiseKit+RxSwift优雅的书写网络请求中,我们尝试了使用PromiseKit和RxSwift共同实现网络请求,在后来我个人的尝试中发现了问题,遂撰文记之。
问题描述
PromiseKit的闭包只会执行一次。
环境配置
- Xcode 8.3
- Swift 3
实例
这一切都是由于实现一个带有缓存的网络请求引起的。为此我们实现一个RxMoyaProvider的Extension,用于实现带有缓存的网络请求。
1 | extension RxMoyaProvider { |
我们基于刚刚实现的这个拓展再实现一个网络请求。注意此处成功的回调result。
1 | func getHomepagePageDataWithCache() -> Promise<HomepageData> { |
然鹅就在这里出现问题了,当我们调用这个方法时:
1 | viewModel.getHomepagePageDataWithCache().then { |
第一次调用因为本地没有缓存,所以打印print($0.packages?.last?.head ?? “”)只会调用一次,然鹅再次运行,存在本地缓存的情况下,该打印语句依然只执行一次。
经过打断点,我发现相关代码均已经执行:
1 | // 请求成功前 |
以上两次 observer.onNext都触发了RxSwift订阅,断点也会停留在订阅里面PromiseKit的闭包result上:1
2
3.subscribe(onNext: {
result($0)
},
但是在最终的闭包里只执行了一次打印:1
2
3then {
print($0.packages?.last?.head ?? "")
}.
原因
经过查询资料,原因如下:
PromiseKit 不具备流的特性,即不支持依赖时间顺序依次传递值,换句话说就是调用闭包 result多次也只能执行一次。这就没办法让我们以完整的声明式的写法完成需求。
所以要想两次都触发并执行RxSwift的订阅,就不能使用PromiseKit来实现这个网络请求。处理很简单,就是把PromiseKit里面实现网络请求的部分提出来改写即可。
1 | provider.offLineCacheRequest(.frontpage) |