浏览器交响曲 (一)浏览器中的js执行机制

浏览器中的js执行机制

今天在网上看到讨论浏览器的工作原理,我发现学习前端这么久了,竟然没有系统的学习过浏览器,知道的都是些零零散散的东西,于是趁现在空余时间,赶紧瞅瞅。

单线程的含义

什么是线程?什么是进程?
进程包含多个线程进程是操作系统最小的执行单位
浏览器是一个多进程(multi-process),一个浏览器只有一个主进程(Browser Process)负责管理Tabs(窗口),协调Renderer Process 和其他Process
渲染进程(Renderer Process)是一个多线程的 它的主线程负责渲染页面和执行js以及事件循环 渲染进程的主线程是一个单线程(同一时间js执行线程和ui渲染线程只有一个在主线程上)
在这里插入图片描述

同步、异步

正是因为js是单线程的,很多的任务只能一个一个排队执行这对用户体验不好,所以就将任务分成了同步任务和异步任务。

简单的理解:

  1. 同步:获取元素、console.log()、alert、定义 变量…

  2. 异步: 事件、定时器、延时器 …

    在这里插入图片描述

    1. 判断任务是同步还是异步
    2. 同步任务直接在主线程执行、异步任务进入事件表并等待一个条件(时间,或者用户操作:例如 点击)。
    3. 注册回调函数 异步任务进入事件队列
    4. 当主线程空闲时(同步执行完成),事件队列中的任务才被推入主线程执行。

完了吗?事情并非如此

console.log('1');

setTimeout(function() {
    console.log('第一个setTimeout');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('第一个setTimeout内的promise');
        resolve();
    }).then(function() {
        console.log('第一个setTimeout内的promise的then')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('第二个setTimeout');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('第二个setTimeout的promise');
        resolve();
    }).then(function() {
        console.log('第二个setTimeout的promise的then')
    })
})

其运行结果如下

在这里插入图片描述
实际上运行的结果并不符合咱们同步异步分类

所以执行的机制是怎样的?(宏任务、微任务)

我们对任务有了更加精细的分类

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

进入整体代码(宏任务)后开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务.并且也要按照同步异步一起嵌套着来。
对照以上代码,其执行顺序为

//A.先执行同步代码
	//1.执行宏任务(整段script代码)
		console.log('1')
	//2.执行微任务(promise)
		console.log('7');
	//3.执行微任务process.nextTick
//Node执行完所有同步任务才执行process.nextTick的任务队列
 		console.log('6');
 	//4. 执行异步代码 promise的then方法
 		console.log('8')
//B.执行异步代码
	//1.执行第一个定时器中的宏任务
		console.log('第一个setTimeout')
	//2.执行第一个定时器中的微任务
		console.log('第一个setTimeout内的promise')
	//3.执行第二个定时器中的宏任务
		console.log('第二个setTimeout')
	//4.执行第二个定时器中的微任务
		console.log('第二个setTimeout内的promise')
	//5.当所有的同步任务执行后执行process.nextTick
		//第一个定时器中的process.nextTick
		console.log('3');
		//第二个定时器中的process.nextTick
		console.log('10');
	//6.执行异步then函数
		//先执行第一个定时器中的
			console.log('第一个setTimeout内的promise的then')
		//先执行第二个定时器中的
		console.log('第二个setTimeout内的promise的then')

在这里插入图片描述

个人理解:

1.先执行同步宏任务,再执行同步微任务,其次是异步微任务
2.执行异步宏任务,再执行同步微任务,其次是异步微任务

希望过路大佬不吝赐教

发布了50 篇原创文章 · 获赞 23 · 访问量 1243

猜你喜欢

转载自blog.csdn.net/qq_44698161/article/details/102835676