Avoid Multiple call to function or Task launch before they return

I am looking for a more elegant way to protect a function from multiple call when the user press multiple time the button quickly in such situation:

    func didPressSignIn() {
        Task { await signInIfAllowed() }
    }
    
    @MainActor
    private func signInIfAllowed() async {
        guard !isSigningIn else {return}
        isSigningIn = true
        lastError = await signIn()
        isSigningIn = false
    }

Consider signIn taking long time (e.g. 30 seconds)... You don't want the button to be visually enabled and clickable with nothing happening. The most proper way is to disable the button until such time user can attempt signing in again (e.g. sign in failed or user has signed out).

1 Like

Thank you for your answer. It is indeed already the case. The button disable state is linked to the isSigninIn. However I was wondering if here is a thing such as

ProtectedTask { await function }
or something like
func signIn() async protected { ... }

which would ditch any attempt to start the same code/task when one is still running.

or maybe the Task itself would be the isSigninIn state.

The trick is simple. Store your task while it's active and remove it when it's done. If you somehow manage to call the synchronous function again then you will check if there is already a task running and ignore the invocation by simply returning and doing nothing.

4 Likes