从今天开始重新捡起博客啦、坚持随学随记、记录自己的成长脚丫子 [开心心.png] … 好了、废话不多说. 开始唠.
众所周知JavaScript是一门 单线程 语言,所有一切 ‘’ 多线程 ‘’ 都是用单线程模拟出来的.
既然js是单线程的, 也就是js任务只能一个一个来;那么问题来了,如果一个任务耗时过长,后面的任务只能等着。对于前端来说, 最重要的是用户体验,让一个用户等很长,无疑是死罪一条 [可怕]
那么就出来了将任务分为两类:
同步任务异步任务先来一段代码片段、看看问题
console.log('开始执行啦') setTimeout(function(){ console.log('定时器开始啦') }, 3000); console.log('代码执行结束啦');输出结果:
// 开始执行啦 // 代码执行结束啦 // (3s后...) 定时器开始啦在这里插入图片描述、
导图来说明、 导图要表达的内容用文字来表述的话:
同步任务、异步任务分别进入不同的’‘场景’’,同步任务进入主线程执行栈;异步任务进入Event Table、并注册回调函数当指定的内容完成时,Event Table将回调函数移入到Event Queue主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行上述过程会不断重复,也就是常说的Event Loop(事件循环)。那么,我们怎么知道主线程执行栈为空呢?js 引擎存在 monitoring process 进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。
`` 那么我们稍微修改下代码:
console.log('开始执行啦') setTimeout(function(){ console.log('定时器开始啦') }, 3000); new Promise(function(resolve) { console.log('promise'); resolve() }).then(function() { console.log('then'); }) console.log('代码执行结束啦');执行结果:
// 开始执行啦 // promise // 代码执行结束啦 // then // 定时器开始啦根据上面的理解及promise的了解、我们不难发现setTimeout 及 then 是异步任务;但是 setTimeout 及 then 他们两个的执行顺序好像让人有点懵;
那么我们进入正题,除了广义的同步任务和异步任务,我们对任务有更精细的定义:
macro-task(宏任务):包括整体代码script,setTimeout,setIntervalmicro-task(微任务):Promise,process.nextTick不同类型的任务会进入对应的Event Queue,比如setTimeout和setInterval会进入相同的Event Queue。
那么我们来解读下上面的代码:
代码作为宏任务,进入主线程先遇到setTimeout, 将其回调函数注册后分发到宏任务Event Queue中接下来遇到Promise, new Promise() 立即执行, then函数分发到微任务 Event Queue 中遇到console.log 立即执行到目前,整体代码script作为第一个宏任务执行结束,那么看看有哪些任务呢?发现then函数的微任务,执行第一次事件循环完成 (宏任务 + 微任务)第二次事件循环开始,从宏任务Event Queue开始,发现setTimeout 的回调函数,立即执行所有任务执行完毕,结束事件循环,宏任务,微任务的关系如图所示:
总结:
javascript是一门单线程语言,不管是什么新框架新语法糖实现的所谓异步,其实都是用同步的方法去模拟的,牢牢把握住单线程这点非常重要事件循环(Event Loop)是js实现异步的一种方法,也是js的执行机制。目前对于执行机制了解就那么多,后期有新的见解继续追加;拜拜👋
