3

I have a function called chaining which chains multiple promises and I want to call that function multiple times. For that, I am using a for loop and I want that with index 0, the chaining function should be executed with index 0. (I have an array of properties ListingArray[] and I want to use ListingArray[0] in one iteration of loop, ListingArray[1] in other iteration and so on).

Here is my chaining function:

func chaining() {
  
 firstly {
            Promise_getIDOfOwnerFromCollection()
        
 }.then { (IdsInCollection)-> Promise<[String]> in
        
        return self.Promise_getOwnerListings(IDs: IdsInCollection)
            
 }.then { (ownerListings) ->Promise<Void> in

            return self.Promise_getReviews(ListingIDs: ownerListings)
           
 }.done { (arg0) in
            
            
            let () = arg0
            print("Work Done")
            
 }.catch { (error) in
            print("Error is \(error.localizedDescription)")
    }
 }

And I am calling that function in loop like this.

for Count in 0...4 {
  chaining()
 }

Now the problem is that the function inside firstly is instantly called 5 times before then is executed. And I want the sequence to be like with Count 0, chaining function should execute one time and then with Count 1, function should execute again.

halfer
  • 19,824
  • 17
  • 99
  • 186
Coder
  • 508
  • 2
  • 13

1 Answers1

1

The behaviour happening in your code is completely expected. Given you're instantiating the chaining 4 times, therefore the firstly job will be executed such number of times.

Instead you will need somehow provide a single instance of work for the firstly.

Currently: execute N times { firstly + rest of the job }

Expected: firstly + execute N times { rest of the job }

Here a code example based on yours.

struct Review {

}

func Promise_getReviews(listingIDs ids: [String]) -> Promise<[Review]> {

}

func Promise_getOwnerListings(IDs ids: [String]) -> Promise<[String]> {

}

func chaining(from initialWork: Promise<[String]>) {
    firstly { when(fulfilled: initialWork) }
        .then(Promise_getOwnerListings)
        .then(Promise_getReviews)
        .done { print("Work Done") }
        .catch { print("Error") }
}

let initialWork = Promise<[String]>(["1","2", "3"])

(0...3).forEach { chaining(from: initialWork) }
Ricowere
  • 707
  • 4
  • 7
  • Thank you so much for your reply! I am new in using `promiseKit` and I am having difficulty in understanding your answer. If possible can you please add some more details to answer, so that I should understand it quickly and award you quickly LOL :) – Coder Jul 16 '20 at 13:14
  • Yeah no problem. Basically the example I did send you should do exactly what you intend to do. The difference I did was to provide a Promise for the firstly block. To avoid create "new job" to do everytime you iterate when you call chaining. That's why as you can view, I'm injecting the Promise, to avoid create new work on the firstly closure. – Ricowere Jul 16 '20 at 13:46
  • About the rest, I'm just using the syntax sugar for swift, which allow you to do then(Promise_getOwnerListings) and I will be more readable than: ``` .then { (IdsInCollection)-> Promise<[String]> in return self.Promise_getOwnerListings(IDs: IdsInCollection) } ``` But they do the same. :) – Ricowere Jul 16 '20 at 13:48
  • Very rightly said. And what about the struct `Review`? What's the logic behind making struct? – Coder Jul 16 '20 at 13:53
  • Nothing special :) I did assume by reading this method signature (Promise_getReviews) that you would be receiving reviews based on the ids provided. Then I did create a dummy struct to represent the example. – Ricowere Jul 16 '20 at 14:03
  • Did it help you? – Ricowere Jul 19 '20 at 09:52
  • I haven't tried it yet , but I hope it will help me in someway! I ll also accept the answer once i ll be able to solve it. Thanks alot for your time and effort bro! – Coder Jul 21 '20 at 10:49
  • Man. I am getting the error in line `let initialWork = Promise<[String]>(["1","2", "3"])`. The error is `Cannot convert value of type '[String]' to expected argument type 'AnyPromise' ` – Coder Jul 23 '20 at 08:41