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.

1 Answer 1

1
+50

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) }
Sign up to request clarification or add additional context in comments.

8 Comments

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 :)
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.
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. :)
Very rightly said. And what about the struct Review? What's the logic behind making struct?
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.