Overview Of Micro Tasks In KnockoutJS

In this article, you will learn about Micro Tasks in KnockoutJS.

Knockout Micro Tasks

Micro Tasks in Knockout allow us to defer a task to achieve asynchronous processing in single threaded environment or, we can say, in the Browsers. First of all, we will look at what macro tasks and micro tasks are in the browsers.

We all know that JavaScript/Browser is single threaded but to process a long running tasks, it is recommended to execute it asynchronously. This makes task queuing very important. The macro task and micro task techniques allow us to queue tasks. The browser user agent requires event loops to coordinate the events, user interactions, callbacks, rendering HTML etc., each event loop has one or more task queues. Task queue allows you to batch macro task and micro task. Let’s understand what macro tasks and micro task are.

Macro Task

Macro Tasks are turn based asynchronous processing. It executes its tasks in a sequential order and in-between browsers, these may do some html rendering as they are non-blocking asynchronous tasks. After processing each macro task, it processes all micro tasks (This type of execution is also called “Go-Around” because event looping is used to process the request) meanwhile we can also add other micro tasks and runs one after another until the queue is exhausted. Example for Macro tasks are setTimeout, setInterval, setImmediate, I/O, UI rendering etc.

Micro Task

Micro task defers execution which will get queued and get executed in next go-around cycle or we can say next event loop. The best part of macro task is it executes entire queue after currently executing script and before next macro task and if we add more micro tasks in between then it executes in the current event loop (go-around cycle) until entire queue get exhausted. Examples of micro tasks are process.nextTick, Promises, Object.observe, MutationObserver.

Let’s look at the execution flow of Micro task and macro task for micro task will be using knockout micro tasks.


In the above code we used Console to log our information. Whenever JavaScript loads in the browser it executes each line in a synchronous manner and we are calling this execution as “Script Execution”. I scheduled some micro tasks and macro tasks and we will observe their execution order.

Inside the viewmodel, a macro task is scheduled as “Macro task 1” in the call back of Macro task 1 we again schedule a micro task and macro task. Following macro task 1, a micro task is scheduled as “Micro task 1” in the callback of Micro task 1 a micro task is scheduled. At the end 2 macro task and a micro task between the macro task is scheduled. Please refer to the code above.

Output of the above code in the browser console is as follows,

Output

In the output, you can observe that Main Execution “Script Execution” starts and after scheduling all tasks, it ends and returns. On completion of the script execution, micro task queue starts executing. It pulls the task 1 and callback executed, inside task 1 and new micro tasks is schedules. We can observe that the micro tasks scheduled inside micro task 1 also get executed after Micro tasks 1 and 2. After looking at the execution flow, we can conclude that 

When tasks from micro task queue start executing it execute all micro tasks until it get exhausted.

Now, Macro tasks from tasks queue have started executing. In task 1, a macro task and a micro task are scheduled. After observation, we can clearly see that all the macro tasks got executed. Then, the micro task got scheduled inside macro task 1 and then, at the end, the macro task is scheduled from macro task 1 executed.

"Once an execution ends, it first executes the micro tasks and then the macro tasks."

Knockout micro task was released with Knockout version 3.4.0. As per the definition of knockout documentation,

“Knockout’s microtask queue supports scheduling tasks to run as soon as possible while still being asynchronous, striving to schedule them to occur before yielding for I/O, reflow, or redrawing.“

Knockout micro tasks are nothing but the browser micro tasks. Knockout had wrapped it and also added functionality to make our life simpler. Let's discuss different options available in Knockout micro tasks.

Schedule a task

For scheduling a task we use ko.task.schedule () function, it has one parameter the callback function. We have to write all out logic inside the callback function

  1. ko.tasks.schedule(function() {  
  2.     // Callback Code  
  3. });   

Cancel a task

To cancel a task, we have to preserve the output from ko.task.schedule () function and pass it in ko.task.cancel () function. The "Cancel" function will not do any action if the task is already executing or canceled. 

  1. var task = ko.tasks.schedule(function() {  
  2.     // Callback Code  
  3. });  
  4. ko.tasks.cancel(task);   

Handling errors

When a task fails to execute, it doesn’t break the queue chain. Instead, it preserves the error(s) and throws an exception once the queue is exhausted. We can handle the errors using below events.

  • onError (knockout error handling event)
  • onerror (windows error handling event)

Whenever new knockout detects any indefinite recursion on micro tasks, it cancels all the remaining tasks in the queue. So that the page won’t get hanged/unresponsive.

When we schedule our very first task, Knockout schedules a flush-out event using browser Micro Task. This ensures that all the subsequent tasks execute properly

References

  • https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
  • http://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context
  • http://ilikekillnerds.com/2016/02/working-with-the-aurelia-task-queue/
  • http://knockoutjs.com/documentation/microtasks.html