返回使用另一个 PromiseKit 承诺的承诺
Posted
技术标签:
【中文标题】返回使用另一个 PromiseKit 承诺的承诺【英文标题】:Returning promise that uses another promise with PromiseKit 【发布时间】:2017-09-23 10:52:17 【问题描述】:这是这个问题所涉及的代码示例:
func executeTask()
fetchApiData().then foos in
return filterData(foos)
.then foos in
return saveData(foos)
.catch
/** handle error **/
func fetchApiData() -> Promise<[Foo]>
return Promise<[Foo]> fulfil, reject in
/* Do a network request, and run through object mapper */
fulfil( myFooCollection )
func filterData(_ data: [Foo]) -> Promise<[Foo]>
return Promise<[Foo]> fulfil, _ in
_ = getIdsToFilter().then ids -> Void in
let filteredData = data.filter foo in
return ids.contains(foo.id)
fulfil(filteredData)
func getIdsToFilter() -> Promise<[Int]>
return Promise<[Int]> fulfil, _ in
/* Do some task here */
fulfil([10,20,30,40])
func saveData(_ data: [Foo]) -> Promise<[Foo]>
return Promise<[Foo]> fulfil, reject in
/* Do some save task here */
fulfil(data)
我特别查询的函数是filterData
。
这是一个非常简单的 Promise 链,获取一些数据,过滤它,然后保存它。但是,过滤过程需要另一个 Promise 的响应才能完成。
如您所见,我已将其实现为一种包装器。我返回了我需要的承诺,但在做这件事之前,该承诺会从其自身内部调用另一个承诺。
我觉得这有点难看,违背了 Promises 的整体构图理念。我认为应该有一种方法可以代替:
func filterData(_ data: [Foo]) -> Promise<[Foo]>
return getIdsToFilter().then ids in
return data.filter foo in
return ids.contains(foo.id)
但是,这当然不像 xcode 所说的那样工作:
Cannot convert return expression of type '[Foo]' to return type 'Promise<[Foo]>' (aka 'Promise<Array<Foo>>')
那么...有没有办法使该功能变平?或者也许我正在做的事情是正确的,应该是这样的?
P.S:我不是在寻找一些过于复杂、过度设计的解决方案 把它弄平。我只是想遵循某种最好的 练习,嵌套不是问题,我只想做 事情“正确”
【问题讨论】:
【参考方案1】:函数func filterData(_ data: [Foo]) -> Promise<[Foo]>
期望返回承诺。
在你的情况下表达
data.filter foo in
return ids.contains(foo.id)
返回Array
的Foo
对象。您必须将 [Foo]
包装到 Promise 对象。请参阅下面的示例
func filterData(_ data: [Foo]) -> Promise<[Foo]>
return Promise _ in
return getIdsToFilter().then ids in
return Promise(value: data.filter return ids.contains($0.id) )
更新: 要了解问题所在,您可以显式声明返回参数的类型。然后你会看到什么类型需要 swift 编译器以及你需要什么类型。这种策略可以帮助我理解编译器错误
func filterData(_ data: [Foo]) -> Promise<[Foo]>
return Promise _ in
return getIdsToFilter().then ids -> Promise<[Foo]> in
return Promise(value: data.filter return ids.contains($0.id) )
【讨论】:
以上是关于返回使用另一个 PromiseKit 承诺的承诺的主要内容,如果未能解决你的问题,请参考以下文章
如果一个已经在运行的 PromiseKit 承诺返回一个未决的承诺的最佳 Swift 模式是啥?