返回使用PromiseKit的另一个承诺的承诺

时间:2017-09-23 10:52:17

标签: ios swift swift3 promise 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:我不是在寻找一些过于复杂,过度设计的解决方案   把它弄平。我只想尝试一些最好的方法   练习,嵌套不是问题所在,我只是想做   事情&#34;正确&#34;

1 个答案:

答案 0 :(得分:1)

函数func filterData(_ data: [Foo]) -> Promise<[Foo]>期望返回promise。 在你的情况下表达式

data.filter { foo in
        return ids.contains(foo.id)
}

返回ArrayFoo个对象。您必须将[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) })
        }
    }
}