事件循环机制分为:浏览器与node.js两种
JavaScript的任务分为两种同步
和异步
,它们的处理方式也各自不同,同步任务是直接放在主线程上排队依次执行,异步任务会放在任务队列中,若有多个异步任务则需要在任务队列中排队等待,任务队列类似于缓冲区,任务下一步会被移到调用栈然后主线程执行调用栈的任务。
调用栈:调用栈是一个栈结构,函数调用会形成一个栈帧,帧中包含了当前执行函数的参数和局部变量等上下文信息,函数执行完后,它的执行上下文会从栈中弹出。
JavaScript是单线程
的,单线程是指 js引擎中解析和执行js代码的线程只有一个(主线程),每次只能做一件事情,然而ajax
请求中,主线程在等待响应的过程中回去做其他事情,浏览器先在事件表注册ajax的回调函数,响应回来后回调函数被添加到任务队列中等待执行,不会造成线程阻塞,所以说js处理ajax请求的方式是异步的。
综上所述,检查调用栈是否为空以及讲某个任务添加到调用栈中的个过程就是event loop,这就是JavaScript实现异步的核心。
浏览器端事件循环中的异步队列有两种:macro(宏任务)队列和 micro(微任务)队列。
常见的 macro-task:setTimeout
、setInterval
、script(整体代码)
、I/O 操作
、UI 渲染
等。
常见的 micro-task: new Promise().then(回调)
、MutationObserve
等。
- 检查macrotask队列是否为空,非空则到2,为空则到3
- 执行macrotask中的一个任务
- 继续检查microtask队列是否为空,若有则到4,否则到5
- 取出microtask中的任务执行,执行完成返回到步骤3
- 执行视图更新
当某个宏任务执行完后,会查看是否有微任务队列。如果有,先执行微任务队列中的所有任务,如果没有,会读取宏任务队列中排在最前的任务,执行宏任务的过程中,遇到微任务,依次加入微任务队列。栈空后,再次读取微任务队列里的任务,依次类推。
node事件循环机制现在坏不是很清楚,下去了解了,再继续更新。