Search code examples
swiftpromisekit

PromiseKit: can't call custom code between then handlers


Just started with PromiseKit and running into a weird compile problem:

  • with firstly: Ambiguous reference to member 'firstly(execute:)' ()
  • without firstly: Unable to infer complex closure return type; add explicit

Not sure what I am doing wrong here.

Promise

func test(someValue: Int) -> Promise<Void> {
    return Promise { seal in
        // do something with someValue
        seal.fulfill(())
    }
}

This works:

firstly {
    test(someValue: 2)
}.then {
    test(someValue: 1)
}.catch { error in
    ...
}

but this one doesn't:

firstly {
    test(someValue: 2)
}.then {
    let dd = 1
    return test(someValue: dd)
}.catch { error in
    ...
}

Solution

  • I've been using Promises quite a bit lately and I've run into similar errors, seems like sometimes all the closures and generics get the best of the compiler.

    What I've found is that you should always have a done call if you have a catch call, add it right before the catch. done means you won't be chaining your promise any more and you can then use a PKFinalizer, like the catch call is.

    And if your promises have parameters you're not using, make sure to add _ in on your next then/done call, or you can add a asVoid() call in between, which discards the result.

    EDIT:

    This week I also had an error where adding an extra line to the closure made it fail. Since what I was doing was converting one promise into multiple promises, I used flatMapThen. There are several methods on Promise that you can use for different results. You can use get if you want to store the result from a promise and continue, or map if you want to convert the result into another type.

    For example, I would translate your failing error into this

    firstly {
        test(someValue: 2)
    }.map {
        1
    }.then {
        test(someValue: $0)
    }.done {
        print("success")
    }.catch { error in
        ...
    }