0

I have a mutation that comprises of a sequence of long-running actions:

useMutation({
  mutationFn: async () => {
    await firstTask()
    await secondTask()
    await thirdTask()
  },
  ...
})

I know I can't cancel the individual tasks once they are in-flight, but I'd like to prevent the execution of any of the tasks that haven't been executed yet once a 'Cancel' button elsewhere in the UI has been clicked.

One option is to pass a ref to mutate and check it in between tasks. If it's false continue. If it's true exit. Then set the ref to false from the cancel button.

1 Answer 1

3

The only thing that can stop a function from running is that function itself. So if you want the mutationFn to stop partway through, add code something like this:

const isCancelled = useRef(false);
useMutation({
  mutationFn: async () => {
    isCancelled.current = false;
    await firstTask()
    // If you prefer, you could throw an error instead of returning
    if (isCancelled.current) return;
    await secondTask()
    if (isCancelled.current) return;
    await thirdTask()
  },
  ...
})
...
<button onClick={() => { isCancelled.current = true }}/>

I know I can't cancel the individual tasks once they are in-flight

That's mostly true, but i want to point out that if the tasks are making fetch requests, fetch supports abort signals. So if that's something you want to do, then instead of storing a boolean isCancelled you can store an AbortController

const controller = useRef(null)
useMutation({
  mutationFn: async () => {
    controller.current = new AbortController();
    const signal = controller.current.signal
    await firstTask(signal); // change this code to use the signal
    if (signal.aborted) return;
    await secondTask(signal);
    if (signal.aborted) return;
    await thirdTask(signal);
  },
  ...
})
...
<button onClick={() => { controller.current?.abort() }}/>
    
Sign up to request clarification or add additional context in comments.

Comments

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.