Thread mechanism and event mechanism ②

JS is single-threaded

We can prove that JS is single-threaded with the following code:

<script type="text/javascript">
  setTimeout(function () {
    
    
    console.log('timeout 2222')
    alert('22222222')
  }, 2000)
  setTimeout(function () {
    
    
    console.log('timeout 1111')
    alert('1111111')
  }, 1000)
  setTimeout(function () {
    
    
    console.log('timeout() 00000')
  }, 0)
  function fn() {
    
    
    console.log('fn()')
  }
  fn()

  console.log('alert()之前')
  alert('------') //暂停当前主线程的执行, 同时暂停计时, 点击确定后, 恢复程序执行和计时
  console.log('alert()之后')
</script>

The alert() function has the function of suspending the execution of the current main thread and suspending the timing at the same time

There are running results to know:
the callback function of setTimeout() is executed on the main thread, and the timer callback function can only be executed after all the codes in the running stack are executed.

Why does js use single-threaded mode instead of multi-threaded mode?
JavaScript's single thread is related to its purpose. As a browser scripting language, JavaScript's primary use is to interact with the user, and to manipulate the DOM. This determines that it can only be a single thread, otherwise it will bring complex synchronization problems.

For example, we can imagine: we now have two threads operating on a div, one of which is styling and the other is deleting. There is such a situation that it is possible: when running one of the threads for styling, suddenly the thread switches, the div is deleted, and an error occurs when returning to the original thread.

We can classify code in JS from another perspective:

  • initialization code
  • callback code

The basic process of js engine executing code: execute initialization code first: including some special code --> callback function (asynchronous execution, callback code will be executed later)

Common callback functions:

  • set timer
  • Bind event listener
  • send ajax request

Special attention: setTimeout() is the initialization code, and the callback function in it is the callback code!

event loop model

Schematic diagram:
insert image description here
Three modules in WEB APIS are responsible for processing the corresponding callback code. From this figure, we can clearly find that the three module processors (provided by the browser) are in the position of sub-threads, while the JS engine is in the position of the main thread (it can only be in the position of the main thread)

2 important components of the model:

  • Event (timer/DOM ​​event/Ajax) management module
  • callback queue

The operation process of the model:
execute the initialization code, and hand over the event callback function to the corresponding module for management. When an event occurs, the management module will add the callback function and its data to the callback queue. Only after the initialization code is executed (it may take a certain period of time), the callback function in the read callback queue will be traversed and executed.

Related concepts:

  • Execution stack: All code is executed in this space
  • task queue
  • message queue
  • event queue
  • The above three queues are equivalent to the callback queue (callback queue)
  • Event polling: cyclically take out the callback function from the task queue and put it into the execution stack for processing (one by one)

At this point, we can explain why the timer is inaccurate in the thread mechanism and event mechanism ① . What really helps us time is the setTimeout callback processing module, the JS engine will not help us time.After the time is up does not mean to execute immediately! Instead, the module puts the callback function into the callback queue, which is in a state of waiting for execution at this time . Only after the code in the execution stack is executed, will the code in the callback queue be placed on the execution stack for execution. When it takes too long to execute the initialization code in the stack, our callback code will enter the execution stack late, giving us the illusion of inaccurate timing.

H5 Web Workers implement multi-threading

Web Workers is a javascript multithreading solution provided by HTML5. We can run some computationally intensive code to a web worker without freezing the user interface. But the child thread is completely controlled by the main thread,and must not manipulate the DOM. So, this new standard doesn't change the single-threaded nature of JavaScript

Steps for usage:

  • Create js files that are executed in separate threads
  • Send message and set callback in js in main thread

Related API

  • Worker: Constructor, loads js files executed by threads
  • Worker.prototype.onmessage: callback function for receiving another thread
  • Worker.prototype.postMessage: send a message to another thread

We simulate a scenario: calculate the Fibonacci sequence with sub-threads, and do not freeze the user interface during the calculation period, and you can operate freely.

Main thread:

<input type="text" placeholder="数值" id="number">
<button id="btn">计算</button>
<script type="text/javascript">
  var input = document.getElementById('number')
  document.getElementById('btn').onclick = function () {
    
    
    var number = input.value

    //创建一个Worker对象
    var worker = new Worker('worker.js')
    // 绑定接收消息的监听
    worker.onmessage = function (event) {
    
    
      console.log('主线程接收分线程返回的数据: '+event.data)
      alert(event.data)
    }

    // 向分线程发送消息
    worker.postMessage(number)
    console.log('主线程向分线程发送数据: '+number)
  }
  // console.log(this) // window

</script>

Sub-thread:

function fibonacci(n) {
    
    
  return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)  //递归调用
}

console.log(this)
this.onmessage = function (event) {
    
    
  var number = event.data
  console.log('分线程接收到主线程发送的数据: '+number)
  //计算
  var result = fibonacci(number)
  postMessage(result)
  console.log('分线程向主线程返回数据: '+result)
  // alert(result)  alert是window的方法, 在分线程不能调用
  // 分线程中的全局对象不再是window, 所以在分线程中不可能更新界面
  //console是每个浏览器都提供的实现,跟window没有关系
}

Notice:

  • alert is a method of window and cannot be called in sub-threads
  • The global object in the sub-thread is no longer window, so it is impossible to update the interface in the sub-thread
  • console is the implementation provided by every browser, it has nothing to do with window

Graphics:
insert image description here
Inadequacies:

  • Can't load JS across domains
  • The code in the worker cannot access the DOM (update the UI)
  • Not every browser supports this new feature

Guess you like

Origin blog.csdn.net/zyb18507175502/article/details/124127128