-1

I'm using PromiseKit to handle flow through a process.

Prior, I did a similar app without promises but decided frick it I'm gonna try promises just because, well, why not?

So I'm throwing a back button in the mix as I did in the prior app. Only problem is, I'm not exactly sure how to handle "reversing" if you want to call it that.

So say I have a flow of

doSomething().then {
    // do something else 
}.then { 
    // do something else 
}.done { 
    // wrap it up, boss
}.catch { 
   // you're an idiot, bud 
}

Say I'm in the first or second part of the chain then and I want to go back up the chain - is this possible?

Is there a link y'all can give me that I can use to read up on how to do that?

I'm thinking I might have to restart the "chain", but then how would I step through the flow....WAIT (light bulb), I can programmatically fulfill the necessary promises with whatever the data is that initially was fulfilled with until I get to the point in the "chain" where I needed to go back to, right?

Advice D:?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
insta catering
  • 151
  • 2
  • 12
  • What you're describing doesn't seem possible. Do you have a concrete example of the behavior you're trying to achieve? – kid_x Aug 05 '19 at 17:23
  • You can always throw and catch in whatever closure you want. – kid_x Aug 05 '19 at 17:24
  • By saving a reference to a promise, you can always fire off different chains of events. Wrote an example as my answer below. – kid_x Aug 05 '19 at 17:32
  • 1
    An example of what you're trying to achieve would be very helpful for us to help you with this answer. – EmilioPelaez Aug 05 '19 at 17:44

3 Answers3

0

You can always have a catch and a then on the same promise.

var somePromise = doSomething()

// first chain
somePromise.catch { error in 
    // handle error 
}

// second chain from the same starting point
somePromise.then { 
    // do something else
}.then { 
   // do something else 
}.catch {
    // you can still catch the error here too
}

You're basically creating two promise chains from the same original promise.

kid_x
  • 1,415
  • 1
  • 11
  • 31
0

No, you can not do that. Once you commit a promise, you can not reverse that. Because the chain is supposed to finish in the descending order, it's cumbersome to track the order in each .then block.

What you can do is, handle the internal logic responsible to fulfill or reject a promise and start the chain from the beginning.

func executeChain() {

    doSomething().then {
        // do something else 
    }.then { 
        // do something else 
    }.done { 
        // condition to 
        executeChain()
    }.catch { 
        // you're an idiot, bud 
    }
}

func doSomething() -> Promise<SomeThing>{

    if (condition to bypass for reversing) {
        return .value(something)
    }

    // Normal execution
}

But if you can improve your question with an actual use case and code then it could help providing more suitable explanation.

Kamran
  • 14,987
  • 4
  • 33
  • 51
0

No you can't but you can set order in array.

bar(promises: [foo1(), foo2(), foo3()])


func bar<T>(promises: [Promise<T>]) {

    when(fulfilled: promises)
    .done { _ in
        // TODO
    }
    .catch { error in
        // When get error reverse array and call it again
        self.bar(promises: promises.reversed())
    }

}

func foo1() -> Promise<Void> {
    return Promise { $0.fulfill(()) }
}

func foo2() -> Promise<Void> {
    return Promise { $0.fulfill(()) }
}

func foo3() -> Promise<Void> {
    return Promise { $0.fulfill(()) }
}

or alternatively

    bar(foo1, foo2, foo3)
    .done { _ in
        // TODO
    }
    .catch { error in
        print(error.localizedDescription)

        self.bar(self.foo3, self.foo2, self.foo1)
        .done { _ in
            // TODO
        }
        .catch { error2 in
            print(error2.localizedDescription)
        }
    }


    func bar<T>(_ promise1: () -> Promise<T>,
                _ promise2: @escaping () -> Promise<T>,
                _ promise3: @escaping () -> Promise<T>) -> Promise<T> {

        return Promise { seal in
            promise1()
            .then { _ in return promise2() }
            .then { _ in return promise3() }
            .done { model in
                seal.fulfill(model)
            }
            .catch {
                seal.reject($0)
            }
        }

    }

    func foo1() -> Promise<Void> {
        return Promise { $0.fulfill(()) }
    }

    func foo2() -> Promise<Void> {
        return Promise { $0.fulfill(()) }
    }

    func foo3() -> Promise<Void> {
        return Promise { $0.fulfill(()) }
    }
Vicaren
  • 654
  • 4
  • 12