实例分析js事件循环机制

  

本文通过实例给大家详细分析了JS中事件循环机制的原理和用法,以下是全部内容:

        var=new开始日期()   setTimeout(函数(){   var=new结束日期   控制台。日志(时间:,结束,开始,“女士”)   },500)   而(新日期()——开始& lt;1000){   }      

有其他语言能完成预期的功能吗? Java,在Java.util.Timer中,对于定时任务的解决方案是通过多线程手段实现的,任务对象存储在任务队列,由专门的调度线程,在新的子线程中完成任务的执行

  

<强> js是单线程的
  

  

JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

  

为了利用多核CPU的计算能力,HTML5提出网络工作者标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

  

函数调用栈和任务队列

  

实例分析js事件循环机制

  

<强>调用栈
  

  

JS执行时会形成调用栈,调用一个函数时,返回地址,参数,本地变量都会被推入栈中,如果当前正在运行的函数中调用另外一个函数,则该函数相关内容也会被推入栈顶。该函数执行完毕,则会被弹出调用栈。变量也随之弹出,由于复杂类型值存放于堆中,因此弹出的只是指针,他们的值依然在堆中,由GC决定回收。

  

事件循环(事件循环),任务队列(任务队列)
  

  

JavaScript主线程拥有一个执行栈以及一个任务队列

  

遇到异步操作(例如:setTimeout (AJAX)时,异步操作会由浏览器(OS)执行,浏览器会在这些任务完成后,将事先定义的回调函数推入主线程的任务队列任务队列中,当主线程的执行栈清空之后会读取任务队列中的回调函数,当任务队列被读取完毕之后,主线程接着执行,从而进入一个无限的循环,这就是事件循环。

  

主线程执行栈,任务队列循环执行,构成事件循环

  

<强>结论
  

  

setTimeout()只是将事件插入了“任务队列”,必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。

  

另一个例子

        (功能测试(){   setTimeout(函数(){console.log (4)}, 0);   新的承诺(功能执行者(解决){   console.log (1);   (var=0;i<10000;我+ +){   我==9999,,解决();   }   console.log (2);   })(函数(){   console.log (5);   });   console.log (3);   })()      

<强> Macrotask,Microtask
  

  

macrotask和microtask是异步任务的两种分类。在挂起任务时,JS引擎会将所有任务按照类别分到这两个队列中,首先在macrotask的队列(这个队列也被叫做任务队列)中取出第一个任务,执行完毕后取出microtask队列中的所有任务顺序执行,之后再取macrotask任务,周而复始,直至两个队列的任务都取完。

  

macro-task:脚本(整体代码),setTimeout, setInterval, setImmediate, I/O, UI呈现
  micro-task:过程。nextTick承诺(这里指浏览器实现的原生承诺),对象。观察,MutationObserver

  

实例分析js事件循环机制

  

<强>结论
  

  

全部代码(脚本)macrotask→microtask队列(含有promise.then)→macrotask (setTimeout)→下一个microtask

  

节点。js的事件循环
  

  

的过程。nextTick,setImmediate
  

  

的过程。nextTick指定的任务总是发生在所有异步任务之前
  

  

setImmediate指定的任务总是在下一次事件循环时执行

        的过程。nextTick(函数(){   console.log (1);   的过程。nextTick(函数B () {console.log (2);});   });   setTimeout(超时函数(){   控制台。日志(“超时解雇”);   },0)            新的承诺(函数(解决){   console.log (“glob1_promise”);   解决();   })(函数(){   console.log (“glob1_then”)   })   process.nextTick(函数(){   console.log (“glob1_nextTick”);   })

实例分析js事件循环机制