2017-09-23 61 views
0

另一个承诺返回承诺下面的代码示例这个问题是关于:使用与PromiseKit

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之一。

这是一个非常简单的承诺链,获取一些数据,过滤它,然后保存它。然而,过滤过程需要其他承诺的响应才能做到。

正如你所看到的,我已经实现了这种包装类型。我回报了我所需要的承诺,但是承诺在做它之前从内部调用另一个承诺。

我觉得这有点丑陋,违背了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) 
} 

回报Foo对象Array。您必须将[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) }) 
     } 
    } 
}