Task modifiers
In Getting started, you’ve seen that you can specify a modifier on the task, either with the dot notation or the options notation. The reason you have this ability is so that you can specify what should happen when multiple, concurrent task instances are running.
In this explainer we will guide you through how each of our modifiers work, with examples of how they behave and hopefully make it clearer to understand when to use one or the other.
Default
By default, every task simply runs as soon as you perform it. This is basically like a function call with the added benefit of having derived state and cancellability. You might’ve seen this simple demonstration on our homepage; but if you didn’t, allow me to introduce you to the friend that will guide us through discovering the task modifiers: the Timeline demo!
Take your time to familiarize yourself with it: you can perform a new task by clicking on the
perform
button and reset the demo with the clear timeline
button. The moment you perform a task,
the timeline will start and it will show you the state of the task. Each task will run for two
seconds and you can either click on it individually to cancel it or click on the cancelAll
button
to nuke them all!
Enqueue
The enqueue
task, as the name suggests, creates a queue of all the task instances after the max
concurrency has been reached. This means that up until the moment max concurrency is exceeded every
task instance will be executed immediately. But if you try to perform a new task instance and the
number of running instances is above the max
level, that new task instance will be stored in a queue
and executed as soon as the number of concurrent instances drops below the max
again.
This is the right kind of task to use when you want to be sure that every task instance is executed
at some point (unless the user leaves the page) but you also don’t want to run them concurrently. A
good use case for this could be uploading a list of files to the server. You want to upload all of
your files but you don’t want to send them all together because that would be too resource intensive
and also makes it harder to handle in case of an error. You can use enqueue
to allow only max
file uploads at a time.
You can play around with it in our Timeline and you may notice a new parameter available for you:
initially set at 1, you can update the max
parameter to allow for more task instances to run at
the same time.
Drop
The drop
task will simply ignore (and thus drop) every perform
that is executed when the max
amount of concurrent task instances is exceeded. With a max concurrency of 1, our example will drop any other tasks that are performed while our initial task is running.
You can think of this kind of task as a sort of throttle; and since the function will be just tossed away you should use this modifier only when you don’t care about the “execution loss”. A good example could be triggering a very expensive task that you want to make sure is only triggered once.
I know you are waiting for it so here’s your drop
Timeline playground:
Restart
The restart
task will cancel the oldest task instance once the max
is exceeded. With max
of 1,
this basically means that every time you perform again you will cancel the last task instance.
You can think of this kind of task as a the good ol’ debounce: if you await for, let’s say, 200ms
before doing any action in a restart
task you can call perform
repeatedly and the actual task
will be executed only once the perform
as not been called for 200ms. This is very useful to
perform fetch requests while the user is typing without inundating your server with requests. Once
the user stops typing the last request will go through without being canceled.
And as per usual, here’s your restart
Timeline playground:
Keep Latest
Finally, we arrive at keepLatest
. It’s a mix of drop
with a sprinkle of enqueue
: once the max
concurrency is exceeded it will drop every new perform
but it will also keep the very last in the
queue to execute it when the max concurrency drop below the max
.
You might need this when you are performing after some very frequent event but you don’t really care about intermediate state because the last one is the important one. Let’s say for example that you are building a collaborative document app. When someone else save the document you want to receive a notification that allow you to reload the document data with the newest additions. If there are two or more saves while you are fetching the data you:
- don’t want to restart the current fetch because you want to show it to the user immediately
- don’t want to drop the new task because you actually want the latest data
- don’t case about the in-between data because the last one is the actual content of the file
That’s where keepLatest
will come in handy!
Conclusion
Task modifiers are very powerful and one of the core features of @sheepdog/svelte
, this explainer
aims to give you all the tools to use them at their best…and some playful time with the timeline
example!