JavaScript the Fun Part


effective-javascript-2

event-loop-event-queue


Two simple concepts that you do not even have to think about them to run your JS code, but understanding them helps you became a better JS developer.

Event Loop

Since JS engine has priority for doing tasks, some of them that have less priority should be executed later.

When are these tasks executed? When the JS engine is idle.

The event loop picks a task from event queue and delivers it to JS engine to be executed; that is it.

Event Queue

Tasks that have less priority are queued for later execution. We call this place event queue because it contains of tasks that should be done, but right now JS engine is busy.

When JS engine does not have anything to do, tasks from this queue are delivered to the engine.

Single Thread

We know and said that JS is a single thread environment which means JS engine only does one task at the same time.

Asynchronous operations using callbacks are not really asynchronous. Saying this I mean parallel execution.

If you do not know about parallel execution here is two simple C programs for running two threads at the same time.

Example of single thread execution in C

Here we only have one thread, main thread.

// only on thread 
#include <stdio.h>
#include <unistd.h>

int main(void) {

    printf( ".......... start of main thread ..........\n" );

    for( int index = 0; index < 9999; ++index ){
        for( int index2 = 0; index2 < 99999; ++index2 ){

        }
    }
    printf( "end of [first] loop in main thread\n" );

    for( int index = 0; index < 9999; ++index ){
        for( int index2 = 0; index2 < 99999; ++index2 ){

        }
    }
    printf( "end of [second] loop in main thread\n" );

    printf( "........... end of main thread ...........\n" );
    return 0;
}

// compile it using GCC
gcc single-thread-execution.c -o single-thread-execution

// notice the time, each loop will take about 3 seconds
time ./single-thread-execution 
.......... start of main thread ..........
end of [first] loop in main thread
end of [second] loop in main thread
........... end of main thread ...........

real	0m7.013s
user	0m7.011s
sys	0m0.000s

What we have here is simple. First loop will take about 3 seconds and then second loop also will take about 3 seconds. The tasks are done one by one, from top to bottom.

Example of two threads execution in C

Here we use POSIX thread or short pthread.

// two threads
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void* thread_function( void* arg ){
    for( int index = 0; index < 9999; ++index ){
        for( int index2 = 0; index2 < 99999; ++index2 ){

        }
    }

    printf( "end of for loop in child thread\n" );
    return NULL;
}

int main(void) {
    printf( ".......... start of main thread ..........\n" );

    pthread_t thr;
    pthread_create( &thr, NULL, thread_function, NULL );

// ignore this loop
//    for( int index = 0; index < 9999; ++index ){
//        for( int index2 = 0; index2 < 99999; ++index2 ){
//
//        }
//    }

    for( int index = 0; index < 9999; ++index ){
        for( int index2 = 0; index2 < 99999; ++index2 ){

        }
    }
    printf( "end of for loop in main thread\n" );

    // join the child thread
    pthread_join( thr, NULL );

    printf( "........... end of main thread ...........\n" );

    return 0;
}


// compile it
gcc  two-threads-execution.c -lpthread -o two-threads-execution

// run it
time ./two-threads-execution
.......... start of main thread ..........
end of for loop in main thread
end of for loop in child thread
........... end of main thread ...........

real	0m3.559s
user	0m6.992s
sys	0m0.000s

You can test and run it as many times as you like; it will be always around 3 seconds, because both loop are run in parallel.

We do NOT have such a thing is JS. The browsers e.g Firefox child processes can have other threads, but the JS engine itself has only one thread to execute codes.

What can we do about this single thread behavior?

It is not that important when we run codes. The important part is about rendering the page.

Rendering a page happens when JS engine is idle. If we add / run too much tasks, then there is no time / chance for other tasks to be processed and rendering page is also a task with less priority than main tasks..

Simple example of this behavior can be seen using a simple SVG animation.

Here is a simple SVG animation that is rendered periodically. Adding an infinite loop, will stop it if we have a weak CPU.

While watching this animation, open your Dev-Tools and add this infinite loop:

function f(){ console.log( "f()" ); f() };
f();

You may not encounter any kind of delay if you have a powerful CPU, but for me it will stop rotating.

For a better test, find a page that has a heavy animation and then try the code there.

And if you use a modern browser you will get something like this, that warns you and wants you to stop it.

infinite-loop.png

Update: Sun Sep 22 2019 09:40:35 GMT+0330 (Iran Standard Time)