bunana bunana - 6 months ago 78
Swift Question

PromiseKit 3.0 chaining

I'm trying to write a function that returns a promise:

func sample() -> Promise<AnyObject> {
return Promise(1)
.then { _ -> Void in
debugPrint("foo")
}.then { _ -> Void in
debugPrint("foo")
}
}


I get an error on the last then statement:

Declared closure result 'Void' (aka '()') is incompatible with contextual type 'AnyPromise'


I was under the impression that 'then' should implicitly returned a promise regardless; Is my thinking wrong? Should I just return a promise explicitly like so?:

func sample() -> Promise<AnyObject> {
return Promise(1)
.then { _ -> Void in
debugPrint("foo")
}.then { _ -> Promise<AnyObject> in
debugPrint("foo")
return Promise(1)
}
}


Thanks

Answer

The promise returned by then(_:) matches the return value of the closure.

func sample() -> Promise<AnyObject> {
    return Promise(1)
    .then { _ -> Void in
        debugPrint("foo")
    }.then { _ -> Void in
        debugPrint("foo")
    }
}

Let me rework your method.

func sample() -> Promise<AnyObject> {
    let p1: Promise<AnyObject> = Promise(1)
    let p2: Promise<Void> = p1.then { _ -> Void in
        debugPrint("foo")
    }
    let p3: Promise<Void> = p2.then { _ -> Void in
        debugPrint("foo")
    }
    return p3
}

You can now see the expected return type of Promise<AnyObject> doesn't match actual return type of Promise<Void>.

If you want to have a method return Promise<AnyObject>, then the last promise in the promise chain must return AnyObject.

func sample() -> Promise<AnyObject> {
    return firstly { _ -> Void in
        debugPrint("foo")
    }.then { _ -> Void in
        debugPrint("foo")
    }.then { _ -> AnyObject in
        1
    }
}