浏览器和Node下的eventLoop

首先先看一道题目

console.log('1')

setTimeout(function callback(){
 console.log('2')
}, 1000)

new Promise((resolve, reject) => {
    console.log('3')
    resolve()
})
.then(res => {
    console.log('4');
})

console.log('5')

1.js工作原理   

  js是单线程的,也就是说是由上至下顺序执行的。但是引入一个新的概念,js中存在异步执行的代码,异步就是在另一个空间去执行这段代码不受之前同步代码的影响。

  例如 setTimeout 函数就是异步的。异步执行的额外空间是哪里来的?那当然是JS所处的运行环境提供的了,而JS最主要的两个运行环境就是:浏览器 和 Node

2.浏览器中的js

  首先浏览器会为代码在内存堆中分配内存,当每执行一段代码,都会把代码压入栈中,当执行完毕后出栈。

  2-1什么是调用栈

function one(a, b) {
 return a * b
}

function two(n) {
 return one(n, n)
}

function three(n) {
 let print= two(n)
 console.log(print)
}

three(5)

  首先在堆中依次存入这四个代码片段,然后代码执行,three(n)、two(n)、one(n)依次入栈,执行过程中按顺序出栈完成这个执行过程。

  2-2eventLoop

  浏览器中的各种 Web API 为异步的代码提供了一个单独的运行空间,当异步的代码运行完毕以后,会将代码中的回调送入到 Task Queue(任务队列)中去,等到调用栈空时,再将队列中的回调函数压入调用栈  中执行,等到栈空以及任务队列也为空时,调用栈仍然会不断检测任务队列中是否有代码需要执行,这一过程就是完整的Event Loop 

console.log('1')

setTimeout(function callback(){
 console.log('2')
}, 1000)

console.log('3')

  

  2-3宏任务和微任务

名称举例(常用)
宏任务 setTimeout 、setInterval 、UI rendering
微任务 promise 、requestAnimationFrame

 

      当宏任务和微任务都处于 Task Queue 中时,微任务的优先级大于宏任务,即先将微任务执行完,再执行宏任务。

      既然区分了宏任务和微任务,那么存放它们的队列也就分为两种,分别为macro task queue(宏队列) 和 micro task queue(微队列)

      根据相关规定,当调用栈为空时,对于这两个队列的检测情况步骤如下:

    1. 检测微队列是否为空,若不为空,则取出一个微任务入栈执行,然后执行步骤1;若为空,则执行步骤2
    2. 检测宏队列是否为空,若不为空,则取出一个宏任务入栈执行,然后执行步骤1;若为空,直接执行步骤1
    3.   ……往复循环

 

 转发来自:https://mp.weixin.qq.com/s?__biz=MzUxNzk1MjQ0Ng==&mid=2247488369&idx=1&sn=31af3f0d6bd664b330b23b89f48dc37e&chksm=f99115a0cee69cb6302ed0b172dd987f03078040b9618a575de12967cfb5c94d6741fd0ea441&mpshare=1&scene=1&srcid=112526HGWF8XkzTpnal4MyQq&sharer_sharetime=1606356750872&sharer_shareid=c75d629ec8b47845d2a96b6237d7746f&version=3.0.36.2008&platform=win#rd

 

posted @ 2020-11-26 11:00  A-dabai  阅读(80)  评论(0编辑  收藏  举报