Skip to content
Learn Netverks
0

How to queue microtask at tail end?

asked 19 hours ago by @qa-offpkjpktllfxlqttw5n 0 rep · 79 views

javascript event loop

In JavaScript, we can queueMicrotask, but this takes the same priority as any newly created promises (e.g. if the codebase is littered with async functions that resolve immediately).

Is there a way I can queue to the tail end of the microtask queue, so that any further scheduled microtasks will take precedence over my scheduled work?

I understand there is no obvious or intentional web API that supports this, but I'm wondering if there are any hacks or quirks that could work?

Please do not mention anything like setTimeout etc., I specifically need to run this code before the browser regains control of the event loop.

Comments on this question (0)

Use comments to ask for clarification — answers go in the answer box below.

Log in to comment on this question.

2 answers

1

There are "user-blocking" tasks you can queue thanks to the prioritized task scheduling API. This API is currently only supported in Chrome and Firefox though.

scheduler.postTask(yourCallback, { priority: "user-blocking" })

Note that unlike tasks, which do have various queues, microtasks are all queued to the one and only microtask-queue. So there is no prioritization possible with these. They're always executed FIFO, when the JS stack is emptied.

Quinn Brooks · 0 rep · 19 hours ago

0

Trying to move your callback at the end of the microtask queue every time you see another was queued after it, is going to be messy and is "fighting" against the FIFO behaviour of the queue.

Instead of trying to give your function a lower priority in the microtask queue, you could try to put your function in queue with lower priority than the microtask queue. Tasks are like that: a new task cannot start before the microtask queue has been depleted.

As in comments you clarify that your function will make final DOM adjustments, you can look at the task that the browser will initiate to update the DOM. This task will process the map of animation frame callbacks before the repaint is performed. So if you schedule your function with requestAnimationFrame, the callback is guaranteed to:

  • not execute before the current task completes, i.e. including the execution of any pending microtasks
  • execute in a new task (initiated by the browser)
  • execute before the next repaint

So the particular goal you have -- to make final DOM adjustments after all other microtasks have done their DOM manipulations, but before they are rendered -- is fulfilled with this approach.

NB: this approach does not prevent that another task might execute between the current task and the task that calls your function. For instance, a setTimeout callback might be able to execute before your function is executed. It is my understanding that this is not problematic for your use case.

Riley Hayes · 0 rep · 19 hours ago

Your answer