Event cycle question

Posted by Norman Graham on Sat, 29 Jan 2022 10:02:30 +0100

preface:

Before that, let's first introduce that Js is a single threaded language. The code is executed from top to bottom. When encountering synchronous code, it will not stop when some code is asynchronous. If it stops, it will be very time-consuming, so there is the concept of task queue at this time. When encountering asynchronous code, Instead of waiting for the asynchronous code to execute the following code, put the asynchronous code into the task queue and then take it to the main thread for execution. Such a cycle is called an event cycle.

I Small trial ox knife

    setTimeout(function () {
  
      console.log(1)
    }, 0);

    new Promise(function executor(resolve) {
      console.log(2);
      for (var i = 0; i < 10000; i++) {
       
        i == 9999 && resolve();
      }
      console.log(3);
    }).then(function () {
   
      console.log(4);
    });
    console.log(5);

Analysis code:

Main thread: console log(2); console. log(3);    console.log(5);

Asynchronous: console Log (4) -- Micro task, console Log (1) -- macro task

Because: the priority of micro task is higher than that of macro task

The final execution result is: 2, 3, 5, 4, 1

Illustration:

II Test test

   // 1,2,3,before timeout,alse before timeout,4,test
    setTimeout(() => {
      // #1
      new Promise(resolve => {
        resolve();
      }).then(() => {
        // #6
        console.log('test');
      });

      console.log(4);
    });

    new Promise(resolve => {
      // Once resolve is called, the callback corresponding to then is added to the micro task queue
      resolve();
      console.log(1)
    }).then(() => {
      // #2
      console.log(3);
      // Execute promise Resolve () adds the following then to the micro task queue
      Promise.resolve().then(() => {
        // #3
        console.log('before timeout');
        // The function returns undefined by default
        // then's function actually returns the default promise resolve(undefined)
        // return Promise.resolve(undefined) / / hidden!!!
      }).then(() => {
        // #4
        Promise.resolve().then(() => {
          // #5
          console.log('also before timeout')
        })
      })
    })
    console.log(2);

Main thread: console log(1), console.log(2);

Task queue: execute micro task first: console log(3);  before timeout; also before timeout;

When executing timer macro task: console log(4); Micro task of timer: console log('test');

The final result of implementation is:

 1,2,3,before timeout,also before timeout,4,test.

III Metamorphosis test

setTimeout(() => {
      // #1
      new Promise(resolve => {
        resolve();
      }).then(() => {
        // #4
        console.log('test');
      });

      console.log(4);
      setTimeout(function () {
        // #5
        Promise.resolve().then(res => {
          // #10
          console.log(444);
        })
      })
      Promise.resolve().then(res => {
        // #6
        console.log(888);
      })
    });

    new Promise(resolve => {
      resolve();
      console.log(1)
    }).then(() => {
      // #2
      console.log(3);
      setTimeout(function () {
        // #3
        Promise.resolve().then(() => {
          // #7: This line does print before timeout, but a micro task is generated after execution
          console.log('before timeout');
          // return Promise.resolve(undefined)
        }).then(() => {
          // #8
          Promise.resolve().then(() => {
            // #9
            console.log('also before timeout')
          })
        })
      })
    })
    console.log(2);

Code analysis:

Main thread: console log(1), console.log(2);

Task queue: console Log (3) -- Micro task; The remaining two timers are macro tasks.

Execute the first timer, console log(4); The first micro test of the timer --- the second micro in the timer. At the same time, a timer is generated to execute the second timer, before timeout, and its callback generates a micro task print also before timeout. There is a timer to execute the most and print 444.

The final execution result is: 1, 2, 3, 4, test, before timeout, also before timeout, 444.

Illustration:

IV Test again

 Promise.resolve().then(() => {
      // #1
      Promise.resolve().then(r => {
        // #2
        console.log('a');
        // return Promise.resolve(undefined)
      }).then(r => {
        // #4
        console.log('h');
      }).then(r => {
        // #6
        console.log('8');
      }).then(r => {
        // #8
        console.log('99')
      });
      // return Promise.resolve(undefined)
    }).then(r => {
      // #3
      console.log('44');
    }).then(() => {
      // #5
      console.log('66')
    }).then(() => {
      // #7
      console.log('7')
    })

Code analysis:

Main thread:

When this asynchrony is executed, two asynchronies are generated at the same time.   return Promise.resolve(undefined).

Task queue:

 console.log('a');

 console.log('44');

The main thread starts executing:

console.log('a');  console.log('44');

After executing a ---------------- generate a new micro task console log('h');

After executing 44 ------- generate a new micro task console log('66')

The main thread starts executing: console log('h');   console.log('66')

And so on The final implementation result is:

 console.log('a');console.log('44');console.log('h');  console.log('66'); console.log('8');console.log('7'); console.log('99').
Illustration:

V Continue testing

                       

Code analysis:

Task queue at this time: generate micro tasks 111 --------- 222.

Main thread:

111, 

Micro task queue at this time:

222

333

The main thread continues to execute:

222 

Micro task queue

333  444-666   555

The main thread continues to execute:

333 444 555  666

in summary:

111,222,333,444,555,666

Vi Impact on the last question

function func(num) {
      return function () {
        // #1
        console.log(num)
      };
    }
    setTimeout(func(1));
    async function async3() {
      // #Calling async4 here does print 5 directly, but it also generates a micro task
      await async4();
      // #2
      console.log(8);
    }
    async function async4() {
      console.log(5)
    }
    // ! As long as the adjustment is carried out immediately
    async3();

    function func2() {
      // #3
      console.log(2);
      async function async1() {
        await async2();
        // #6
        console.log(9)
      }
      async function async2() {
        console.log(5)
      }
      async1();
      setTimeout(func(4))
    }
    setTimeout(func2);
    setTimeout(func(3));
    new Promise(resolve => {
        console.log('Promise');
        resolve()
      })
      .then(() => console.log(6)) // #4
      .then(() => console.log(7)); // #5
    console.log(0);

Resolution code:

Before doing this problem, you should first know that the code behind await is asynchronous.

After the first pass:

Main thread:

   console.log(5)

  console.log('Promise');

  console.log(0);

Macro task:

 setTimeout(func(1));

setTimeout(func2);

  setTimeout(func(3));

Micro task:

  console.log(8);

 console.log(6)

Callback:

 console.log(6)-----------console.log(7))

The main thread needs to take micro tasks to execute

Main thread:

  console.log(8);

 console.log(6)

console.log(7)) ----------- the callback also generates asynchronous tasks

Current output results:

   console.log(5)

  console.log('Promise');

  console.log(0);

  console.log(8);

 console.log(6)

console.log(7)) ----------- the callback also generates asynchronous tasks

Start processing macro tasks:

 setTimeout(func(1));------------------1

setTimeout(func2);

 console.log(2); 

 console.log(5)

Generate micro task: console log(9)

Generate macro task: setTimeout(func(4))

Current macro tasks: setTimeout(func(3));   setTimeout(func(4))

To execute:

Output: 1, 2, 5, 9, 3, 4

The final result of implementation is:

 console.log(5)

  console.log('Promise');

  console.log(0);

  console.log(8);

 console.log(6)

console.log(7)) ----------- the callback also generates asynchronous tasks

1 ,2,5,9,3,4

Illustration:

Topics: Javascript Front-end Vue.js