JavaScript 运行机制

2023-07-29  本文已影响0人  scrollHeart

JavaScript作为浏览器脚本语言,主要用途是与用户互动,以及操作DOM

JavaScript语言特点:

单线程, 同一个时间只能做一件事。所有任务需要排队,形成"任务队列"。

"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。

所有任务可以分成:

js的运行机制

(1)所有同步任务都在主线程上执行,形成一个执行栈。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",

(4)主线程不断重复上面的第三步。

只要主线程空了,就会去读取"任务队列",这个过程会不断重复,这就是JavaScript的运行机制


Event Loop(事件循环),主线程从"任务队列"中读取事件,这个过程是循环不断的。

主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数

回调函数(callback),会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

由于存在"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

setTimeout[1]

 setTimeout(function(){
     console.log('定时器开始啦')
 },3000);
 
 new Promise(function(resolve){
     console.log('马上执行for循环啦');
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log('执行then函数啦')
 });
 
 console.log('代码执行结束');

首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

遇到 new Promise直接执行,打印"马上执行for循环啦"

遇到then方法,是微任务,将其放到微任务的【队列里】

打印 "代码执行结束"

本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"

到此,本轮的event loop 全部完成。下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"

JavaScript 运行机制详解:再谈Event Loop

HTML系列:macrotask和microtask

深入理解JS引擎的执行机制


  1. 3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,,只有在主线程空闲时才会执行。主线程执行内容很多,执行时间超过3秒,比如执行了10秒,那么这个函数只能10秒后执行了

上一篇 下一篇

猜你喜欢

热点阅读