Correctly chain multiple promises in PromiseKit 6

落爺英雄遲暮 提交于 2020-07-21 10:20:51

问题


I'm using Promisekit 6 and have 3 functions defined, all of which return promises. the first fetches data from a local database and the second from an online API server. the third, Foo, checks if the data with a given id exists locally, otherwise it checks online and returns it.

I'm having trouble figuring out how to correctly chain the promises. Below is what I came up with thus far, but I'm not certain if creating a new promise is a good idea. Any feedback is appreciated. Thanks :)

func daoClient.get(id: String) -> Promise<Any> {
    return Promise { seal in
        do {
            let realm = try Realm()
            if let data = realm.object(ofType: DataEntity.self, forPrimaryKey: id) {
                seal.fulfill(alert)
            } else {
                seal.reject(Errors.DataError(error: "no data found with id \(id)"))
            }
        } catch {
            seal.reject(error)
        }
    }
}

func apiClient.get(id: String) -> Promise<swiftyJson.JSON> {
    return self.oiRequestClient.request(self.endpoint, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil)
        .responseJSON()
        .compactMap { (arg) -> JSON? in
            let json = JSON(arg.json)

            if let response = arg.response.response, response.statusCode > 399 {
                let error = json["error"].dictionary?.description
                throw Errors.NetWorkError(error: error)
            } else {
                return json
            }
        }
}


func Foo(id: String) -> Promise<Any> {
    return Promise { seal in
        daoClient
            .get(id: id)
            .done { data in
                seal.fulfill(data)
            }.recover { (error: Error) in
                return self.apiClient
                .get(id: id)
                .done { data in
                    seal.fulfill(data)
                }
            }.catch { error in
                seal.reject(error)
            }
    }
}

回答1:


You are not handling error in "recover", that's a strange pattern imo, anyway it's better to not wrap promises like you did, and chain more "vertically" like this :

func Foo(id: String) -> Promise<Any> {
    return firstly {
        return daoClient.get(id: id)
    }.compactMap { data in
        return data
    }.recover { _ -> Promise<swiftyJson.JSON> in
        return self.apiClient.get(id: id)
    }.compactMap { data in
        return data
    }
}

"return Promise { seal in" is only needed when you need to wrap non-promise asynchronous code



来源:https://stackoverflow.com/questions/50928472/correctly-chain-multiple-promises-in-promisekit-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!