An async event wrapper that is cancelled when a new one starts.
When a new event is started, the previous caller will receive a
cancellation error, instead of being hung up indefinitely.
If you want every caller to receive the latest result
instead of a cancellation error, use latest instead.
Example
import { serial } from"@pistonite/pure/sync";
// helper function to simulate async work constwait = (ms: number) =>newPromise((resolve) =>setTimeout(resolve, ms));
// Create the wrapped function constexecute = serial({ // This has to be curried for type inferrence fn: (checkCancel) =>async () => { for (leti = 0; i < 10; i++) { awaitwait(1000); // The cancellation mechanism throws an error if is cancelled checkCancel(); } return42; } });
// execute it the first time constpromise1 = execute(); awaitwait(3000);
// calling event.run a second time will cause `checkCancel` to return false // the next time it's called by the first event constpromise2 = execute();
It's the event handler's responsibility to check if the event is cancelled by
calling the checkCancel function. This function will throw if the event
is cancelled, and the error will be caught by the wrapper and returned as an Err
Note that even if you don't check it, there is one final check before the result is returned.
So you will never get a result from a cancelled event. Also note that you only need to check
after any await calls. If there's no await, everything is executed synchronously,
and it's theoretically impossible to cancel the event. However, this depends on
the runtime's implementation of promises.
Handling cancelled event
To check if an event is completed or cancelled, simply await
on the promise check the err
import { serial } from"@pistonite/pure/sync";
constexecute = serial({ fn: (checkCancel) =>async () => { // your code here ... } }); constresult = awaitexecute(); if (result.err === "cancel") { console.log("event was cancelled"); } else { console.log("event completed"); }
You can also pass in a callback to the constructor, which will be called
when the event is cancelled. The cancel callback is guaranteed to only fire at most once per run
import { serial } from"@pistonite/pure/sync";
constonCancel = (current: bigint, latest: bigint) => { console.log(`Event with serial ${current} is cancelled because the latest serial is ${latest}`); };
constexecute = newSerial({ fn: ..., onCancel, });
Exception handling
If the underlying function throws, the exception will be re-thrown to the caller.
An async event wrapper that is cancelled when a new one starts. When a new event is started, the previous caller will receive a cancellation error, instead of being hung up indefinitely.
If you want every caller to receive the latest result instead of a cancellation error, use
latest
instead.Example
Passing in arguments
TypeScript magic is used to ensure full type-safety when passing in arguments.
Getting the current serial number
The serial number has type
bigint
and is incremented every timerun
is called.You can have an extra argument after
checkCancel
, that will receive the current serial number, if you need it for some reason.Checking for cancel
It's the event handler's responsibility to check if the event is cancelled by calling the
checkCancel
function. This function will throw if the event is cancelled, and the error will be caught by the wrapper and returned as anErr
Note that even if you don't check it, there is one final check before the result is returned. So you will never get a result from a cancelled event. Also note that you only need to check after any
await
calls. If there's noawait
, everything is executed synchronously, and it's theoretically impossible to cancel the event. However, this depends on the runtime's implementation of promises.Handling cancelled event
To check if an event is completed or cancelled, simply
await
on the promise check theerr
You can also pass in a callback to the constructor, which will be called when the event is cancelled. The cancel callback is guaranteed to only fire at most once per run
Exception handling
If the underlying function throws, the exception will be re-thrown to the caller.