Swift 2 Promisekit 3 链接 asyc 方法的疯狂

Posted

技术标签:

【中文标题】Swift 2 Promisekit 3 链接 asyc 方法的疯狂【英文标题】:Swift 2 Promisekit 3 chaining asyc methods madness 【发布时间】:2016-01-22 19:20:30 【问题描述】:

我有 3 个承诺,每个承诺单独运作:

DataManager.reverseGeoCodePromise("42.527328", longitude: "-83.146928").then  data in
    print("Zip \(data)")


DataManager.getEnviroUVWithZipPromise("48073").then  data in
    print("UV \(data.getUVIndex())")


DataManager.getCurrentForZipPromise("48073").then  data in
    print("AirNow \(data[0].Latitude)")

我一直在尝试遵循 (sparce) 关于 promisekit 3 的快速文档(以及用尽的谷歌和堆栈溢出)。我尝试链接这些异步方法根本不是同步执行的——所有的 print(data) 都是空的,但是方法中的断点显示了数据。

DataManager.reverseGeoCodePromise("42.527328", longitude: "-83.146928").then  data in
    print("Promise Zip \(data)")
.then  data -> Void in
    DataManager.getEnviroUVWithZipPromise("48073")
    print("Promise Enviro \(data)")
.then  data -> Void in
    DataManager.getCurrentForZipPromise("48073")
    print("Promise AirNow \(data)")
.error  error in
    print("Promise doh!")

我希望将第一次调用 (zip) 中的数据传递给后续调用,并能够处理最后一次调用之后的所有调用中的数据。任何见解都非常感谢!

【问题讨论】:

在此处查看我的答案以了解语法。 ***.com/questions/34501537/… 【参考方案1】:

您的问题是您的闭包返回Void 而不是Promise<T>then 块不希望返回任何内容,因此它会继续执行,无需等待承诺被履行或拒绝。

这是一个完整的例子。您可以将其粘贴到 PromiseKit 游乐场进行测试。

var zipcode: String?

UIApplication.sharedApplication().networkActivityIndicatorVisible = true

firstly 

    return DataManager.reverseGeoCodePromise("42.527328", longitude: "-83.146928")

.then  (data: String) -> Promise<String> in
    // ^ I expect to receive a string. I promise to return a string        

    zipcode = data
    // ^ Store zip code so it can be used further down the chain

    print("Returned from reverseGeoCodePromise: \(data)")
    return DataManager.getEnviroUVWithZipPromise(zipcode!)

.then  (data: String) -> Promise<String> in
    // ^ I expect to receive a string. I promise to return a string

    print("Returned from getEnviroUVWithZipPromise: \(data)")
    return DataManager.getCurrentForZipPromise(zipcode!)

.then  (data: String) -> Void in
    // ^ I expect to receive a string. I return nothing

    print("Returned from getCurrentForZipPromise: \(data)")

.always 

    UIApplication.sharedApplication().networkActivityIndicatorVisible = false

.error  error in

    switch error 
    case DataManagerError.FailedDueToX:
        print("got an error")
    default:
        print("unknown error")
    


自定义错误类型示例:

enum DataManagerError: ErrorType 
    case FailedDueToX

示例数据管理器承诺:

class DataManager 
    static func reverseGeoCodePromise(lat: String, longitude: String) -> Promise<String> 
        return Promise  fulfill, reject in
            if 1 == 1 
                fulfill("48073")
             else 
                reject(DataManagerError.FailedDueToX)
            
        
    

    static func getEnviroUVWithZipPromise(zip: String) -> Promise<String> 
        return Promise  fulfill, reject in
            if 1 == 1 
                fulfill("Two")
             else 
                reject(DataManagerError.FailedDueToX)
            
        
    

    static func getCurrentForZipPromise(zip: String) -> Promise<String> 
        return Promise  fulfill, reject in
            if 1 == 1 
                fulfill("Three")
             else 
                reject(DataManagerError.FailedDueToX)
            
        
    


【讨论】:

请注意,您不必一开始就使用firstly,我只是更喜欢它的外观。 谢谢!实际上,其中两个方法返回自定义对象,而不是 String ...发布在这里: 我使用字符串只是为了说明。您可以替换为适合您的确切场景的数据类型。关于您的邮政编码注释,您可以将其存储在承诺链之外。我会更新我的答案,告诉你怎么做。 了解,我在原始帖子中发布了一个工作示例,位于您的答案下方。在这一点上没有看到 - 可能没有满足事实上的行为(新手)。期待你的更新。我还可以在第三次调用的结果中使用第二次调用的返回值吗? 您的更改是对我的回答的推荐编辑。版主拒绝了编辑,因为您提出了其他问题。如果您需要提出后续问题,只需使用 cmets 区域(就像您刚才所做的那样)或编辑您的原始问题。

以上是关于Swift 2 Promisekit 3 链接 asyc 方法的疯狂的主要内容,如果未能解决你的问题,请参考以下文章

PromiseKit 3 for Swift2 中的“when”是不是已重命名?

如何使用 PromiseKit 在 Swift 3 中手动触发 Promise

PromiseKit 不能与 Swift 2 和 Xcode 7 一起编译

While Loop 在 Promisekit 完成运行并在 Swift 中返回正确的值之前递增并重新运行

使用 PromiseKit 从 Objective C 到 Swift 的桥接

Swift 4 - 使用 PromiseKit 调用嵌套