Chaining multiple async functions in Swift

2019-07-20 10:13发布

I'm trying to write a series of functions that will validate the user's information before asking them to confirm something. (Imagine a shopping app).

  1. I first have to check that the user has added a card.
  2. Then I have to check that they have sufficient balance.
  3. Then I can ask them to confirm the payment.

I can write the async method to check the card something like ...

func checkHasCard(completion: (Bool) -> ()) {
    // go to the inter webs
    // get the card
    // process data
    let hasCard: Bool = // the user has a card or not.
    completion(hasCard)
}

This can be run like this...

checkHasCard {
    hasCard in
    if hasCard {
        print("YAY!")
    } else {
        print("BOO!")
    }
}

But... now, based off that I have to do various things. If the user does have a card I then need to continue onwards and check there is sufficient balance (in much the same way). If the user does not have a card I present a screen for them to add their card.

But it gets messy...

checkHasCard {
    hasCard in
    if hasCard {
        // check balance
        print("YAY!")
        checkBalance {
            hasBalance in
            if hasBalance {
                // WHAT IS GOING ON?!
                print("")
            } else {
                // ask to top up the account
                print("BOO!")
            }
        }
    } else {
        // ask for card details
        print("BOO!")
    }
}

What I'd like instead is something along the lines of this...

checkHasCard() // if no card then show card details screen
    .checkBalance() // only run if there is a card ... if no balance ask for top up
    .confirmPayment()

This looks much more "swifty" but I'm not sure how to get closer to something like this.

Is there a way?

1条回答
相关推荐>>
2楼-- · 2019-07-20 10:44

Asynchronous operations, ordered and with dependencies? You're describing NSOperation.

Certainly you can chain tasks using GCD:

DispatchQueue.main.async {
    // do something
    // check something...
    // and then:
    DispatchQueue.main.async {
        // receive info from higher closure
        // and so on
    }
}

But if your operations are complex, e.g. they have delegates, that architecture completely breaks down. NSOperation allows complex operations to be encapsulated in just the way you're after.

查看更多
登录 后发表回答