From 0409089ec76d019ca60b74d271b62bbed236ec8b Mon Sep 17 00:00:00 2001 From: Erik Huelsmann Date: Fri, 13 Dec 2024 20:09:46 +0100 Subject: [PATCH] Add docs explaining how to 'cancel' invoke() (#223) Add docs explaining how to 'cancel' invoke() Closes #185 --- .changeset/tender-humans-brush.md | 5 +++++ docs/api/invoke.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .changeset/tender-humans-brush.md diff --git a/.changeset/tender-humans-brush.md b/.changeset/tender-humans-brush.md new file mode 100644 index 00000000..4f0b4876 --- /dev/null +++ b/.changeset/tender-humans-brush.md @@ -0,0 +1,5 @@ +--- +"robot3": patch +--- + +Documentation for advanced use of 'invoke()' diff --git a/docs/api/invoke.md b/docs/api/invoke.md index 51fc3c8d..07f0218d 100644 --- a/docs/api/invoke.md +++ b/docs/api/invoke.md @@ -196,3 +196,34 @@ const machine = createMachine({ error: state() }) ``` + +## Cancellation + +JavaScript does not support cancellation of promises: the action which will +resolve the promise will run to completion or until it encounters an error. + +There are situations where the result of the promise no longer matters. The +machine should proceed to a different action, or simply stop changing state +entirely. To achieve this with the `invoke` state, an extra event can be +added to the state like the `cancel` event in the example below. + +```js +import { createMachine, invoke, reduce, state, transition } from 'robot3'; + +const loadTodos = () => Promise.reject("Sorry but you can't do that"); + +const machine = createMachine({ + start: invoke(loadTodos, + transition('cancel', 'cancelled'), + transition('done', 'loaded', + reduce((ctx, ev) => ({ ...ctx, todo: ev.data })) + ) + ), + cancelled: state(), + loaded: state() +}) +``` + +By moving out of `start` state before the promise returned by `loadTodos` +resolves, the function result will be discarded: the machine finds that it +is no longer in the state from which is was invoked and discards the event.