宏定义与微定义(JavaScript 执行机制)
关于JAVASCRIPT
javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的,一切javascript多线程都是纸老虎!浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线 程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产 生不同的异步事件.
javascript的代码分为两种:
同步代码与异步代码
同步代码
准则一、同步代码,编写顺序就是执行顺序。
console.log(1)
console.log(2)
console.log(3)
js引擎的主线程负责执行代码,由于只有一个线程,执行当然是同步的,即按照顺序来。
异步代码
异步分为三种:
第一,鼠标的键盘事件触发,例如onclick,onkeydown等等
第二,网络的事件触发,例如onload,onerror等等
第三,定时器,例如setTimeout,setInterval
例如:
settimeout(()=>
{
console.log("内层宏事件")
},0)//setTimeout是一个异步的任务,第二参数真正的含义是在0毫秒之后,
//将代码插入到队列中,而不是在0毫秒之后执行
console.log("外层宏事件");
/* 执行结果
外层宏事件
内层宏事件
*/
同步任务与异步任务
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
执行机制
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(taskqueue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。、
流程如下图
接下来我们就可以更好的理解宏任务与微任务拉
我们先看下面这段代码
console.log("外层宏事件1")
setTimeout(() => {
console.log("内层宏事件")
}, 0);
async function actions(){
await calling() //外层宏定义
setTimeout(() => {
console.log("内层宏事件2") //内层宏定义
}, 0);
console.log("微事件1") //微事件
}
actions()
new Promise((resolve)=>
{
console.log("外层宏事件3"); //外层宏定义
resolve();
console.log("外层宏事件4")
}).then(()=>
{
setTimeout(() => {
console.log("内层宏事件3") //内层宏定义
}, 0);
console.log("微事件2") //微事件
}).catch(()=>
{
console.log("微事件2")
})
function calling(){
console.log("外层宏定义2")
}
面对上面这个纷繁复杂好的代码,有Promise、async/await,settimeout三个函数,那到底这些函数的执行顺序如何呢?
对照这结果我们来复现一遍
由上面的知识我们可以明白,基本的执行顺序为
外层宏事件=>>微事件=>>内层宏事件
外层宏定义我们可以理解为同步执行的代码事件,他们有顺序进入执行栈,满足按照先入先出的原则,实现同步执行机制。
微事件一般可以认为实在await+函数名后执行的事件与Promise中then与catch内执行的事件,会按照顺序进入microQueue微事件栈中。EventQueue会先向microQueueu发出请求,若microqueue(微任务)有任务,则会进入Eventqueue中等待执行站内为空时执行该任务。当执行栈为空的时候就会向EventQueue中拿取任务。
内层宏任务一般设定在settimeout中,会进入macroQueue(即宏任务队列),执行顺序依然为先进先出,后进后出。
新手前端人员,打这个来加深印象,有许多不足的地方还望见谅
这里也参考了许多博主的文章,大家可以看看。
setTimeout运行机制
https://blog.csdn.net/qingwenxiutong/article/details/52397676
深入理解JavaScript的执行机制(同步和异步)
https://blog.csdn.net/jingjingshizhu/article/details/93459799
js中的宏任务与微任务
https://segmentfault.com/a/1190000020225668
此外大家还可以观看一下 《Philip Roberts:到底什么是Event Loop?》
https://search.bilibili.com/allkeyword=Philip%20Roberts&from_source=webtop_search&spm_id_from=333.788