如果一个已经在运行中,返回一个待处理的PromiseKit承诺的最佳Swift模式是什么?

时间:2016-04-13 19:14:05

标签: swift promisekit

我有一些昂贵的承诺在不同的地方被召唤。理想情况下,我想把现有的飞行中的承诺(带有可选的力量)联系起来,所以我发现自己做了这样的事情:

class Expensive {
  var fooPromise : Promise<Foo>?
  var barPromise : Promise<Bar>?

  func doExpensiveFoo(force: bool = false) -> Promise<Foo> {
    if let existing = fooPromise where existing.pending || (existing.fufilled && !force) {
      // Return the existing promise
      return existing
    }

    // Start a new Foo
    return firstly {
       // ...
    }
  }

  func doExpensiveBar(force: bool = false) -> Promise<Bar> {
    if let existing = barPromise where existing.pending || (existing.fufilled && !force) {
      // Return the existing promise
      return existing
    }

    // Start a new Bar
    return firstly {
       // ...
    }
  }
}

但这感觉就像是一个相当数量的样板(每个承诺的局部变量,以及每个函数开头的现有块),所以我想知道是否有人看到了一个很好的模式来抽象掉变量和包装器?

要从Python中借用一个术语,我正在寻找一个隐藏所有这些内容的装饰器。类似的东西:

class Expensive {

  private func startFoo() -> Promise<Foo> {
    return firstly {
       //..
    }
  }

  public doExpensiveFoo = wrapExpensive(startFoo)

}

有任何建议,还是我应该看看自己的推荐?

2 个答案:

答案 0 :(得分:0)

在你的例子中,我没有看到任何Foo和Bar的共同基础。但即使如果他们将拥有一个Swift仍然不支持泛型类型参数的协方差。首先,您需要为这两种类型创建一个通用协议。也许这有助于你走上正轨:

Storing generic objects in Swift Array

答案 1 :(得分:0)

我不是专家,但这种模式对我有用:

private var fooPromise : Promise<Foo>?

func doExpensiveFoo() -> Promise<Foo> {
    if let fooPromise = self.fooPromise, fooPromise.isPending {
        // return the pending promise
        return fooPromise
    }

    // reassign a newly created promise
    fooPromise = firstly { 
        // do your thing
        ...
    }

    return fooPromise!
  }

我喜欢这种模式的方法是该方法在内部处理挂起状态,并且如果在完成后调用,则promise会自动重新执行。这允许呼叫者不了解内部机制或承诺的状态。显然,如果你需要调用者作为决定的一部分,那么请保持&#34; force&#34;国旗的方法。

相关问题