一文讲清同步异步,消息队列,宏任务 微任务...

单线程多线程

什么是线程进程?

进程:是cpu分配资源的最小单位;(是能拥有资源和独立运行的最小单位)

线程: 是cpu调度的最小单位;(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

比喻:进程就是一个公司,每个公司都有自己的资源可以调度;公司之间是相互独立的;而线程就是公司中的每个员工(你,我,他),多个员工一起合作,完成任务,公司可以有一名员工或多个,员工之间共享公司的空间

比喻:1万块儿砖搬上10楼,整栋楼就是进程。一个电梯运就是单线程,多个电梯一起运就是多线程.

什么是单线程多线程?

单线程:

单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。单线程就是进程里只有一个线程。

多线程:

在单个程序中同时运行多个线程完成不同的工作,称为多线程。

浏览器是多进程的:

放在浏览器中,每打开一个tab页面,其实就是新开了一个进程,在这个进程中,还有ui渲染线程,js引擎线程,http请求线程等。 所以,浏览器是一个多进程的。

JS是单线程的:

JavaScript是单线程的,也就是说,同一个时刻,JavaScript只能执行一个任务,其他任务只能等待。

为什么JS要设计成单线程的?

JavaScript 的设计就是为了处理浏览器网页的交互(DOM操作的处理、UI动画等),决定了它是一门单线程语言。如果有多个线程,它们同时在操作 DOM,那网页将会一团糟。

这主要和js的用途有关,js是作为浏览器的脚本语言,主要是实现用户与浏览器的交互,以及操作dom;这决定了它只能是单线程,否则会带来很复杂的同步问题。 举个例子:如果js被设计了多线程,如果有一个线程要修改一个dom元素,另一个线程要删除这个dom元素,此时浏览器就会一脸茫然,不知所措。所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变

扫描二维码关注公众号,回复: 15451041 查看本文章

同步异步 宏任务 微任务

为什么任务要分为同步任务和异步任务?

那如果一个任务的处理耗时(或者是等待)很久的话,如:网络请求、定时器、等待鼠标点击等,后面的任务也就会被阻塞,也就是说会阻塞所有的用户交互(按钮、滚动条等),会带来极不友好的体验。

所以,又引入了异步任务。

同步任务:同步任务不需要进行等待可立即看到执行结果,比如console

异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求

异步任务又分为宏任务和微任务

为什么要有微任务宏任务?

有些任务优先级更高,我们js允许它插队优先执行

常见的宏任务和微任务:

// 宏任务:script 定时器 延时器(setTimeout,setInterval) ajax请求 ,dom事件

// 微任务: promise.then promise.catch

事件循环(Event Loop)与消息队列(task queue)

概念_EventLoop事件循环:

EventLoop事件循环的是在浏览器中的一个概念.浏览器中的EventLoop:js是单线程的,一次只能做一件事。js在浏览器这个宿主环境中运行。用户交互,定时器,网络请求等等浏览器中的事件会产生对应的任务,任务多了要在任务队列中排队,浏览器的主线程依次取出

任务来执行,此过程不断重复从而形成一个循环,称为eventloop。

执行顺序:


    // 宏任务 微任务 如何执行的
    //  1. 先执行宏任务
    //  2. 当宏任务执行结束了,在执行所有的微任务(如果没有微任务,就不需要执行)
    //  3. 继续执行下一个宏任务了
同步异步代码如何执行:
先把所有的同步代码添加到任务队列,排在前面,然后把异步代码排到同步代码的后面(注意如果此时,好几个异步代码都有时间,比如过几秒后再执行,那么谁先被放任务队列中,谁的等待时间短就会被先放进去)

宏任务微任务面试题:

<!-- 第一题 -->
<!-- <script>
  console.log(1)
  setTimeout(function () {
    console.log(2)
    new Promise(function (resolve) {
      console.log(3)
      resolve()
    }).then(function () {
      console.log(4)
    })
  })

  new Promise(function (resolve) {
    console.log(5)
    resolve()
  }).then(function () {
    console.log(6)
  })
  setTimeout(function () {
    console.log(7)
    new Promise(function (resolve) {
      console.log(8)
      resolve()
    }).then(function () {
      console.log(9)
    })
  })
  console.log(10)
</script> -->

<!-- 第二题 -->
<!-- <script>
  console.log(1)
  setTimeout(() => {
    console.log(2)
  }, 0)
  console.log(3)
</script>
<script>
  console.log(4)
  setTimeout(() => {
    console.log(5)
  }, 0)
  console.log(6)
</script> -->

<!-- 第三题 -->
<script>
  console.log(1)

  setTimeout(function () {
    console.log(2)
  }, 0)

  const p = new Promise((resolve, reject) => {
    console.log(3)
    resolve(1000) // 标记为成功
    console.log(4)
  })

  p.then((data) => {
    console.log(data)
  })

  console.log(5)
</script>

<!-- 第四题 -->
<script>
  new Promise((resolve, reject) => {
    resolve(1)

    new Promise((resolve, reject) => {
      resolve(2)
    }).then((data) => {
      console.log(data)
    })
  }).then((data) => {
    console.log(data)
  })

  console.log(3)
</script>
<!-- 第五题 -->
<!-- <script>
	console.log(1)
	async function fnOne() {
		console.log(2)
		await fnTwo() // 右结合先执行右侧的代码, 然后等待\
		console.log(3)

		// █
		//await 函数()
		// 其它代码
		// 这里会执行这个函数,然后把这儿的其它代码放到微任务里.详见图
	}
	async function fnTwo() {
		console.log(4)
	}
	fnOne() //调用才执行
	setTimeout(() => {
		console.log(5)
	}, 2000)
	let p = new Promise((resolve, reject) => {
		// new Promise()里的函数体会马上执行所有代码
		console.log(6)
		resolve()
		console.log(7)
	})
	setTimeout(() => {
		console.log(8)
	}, 0)
	p.then(() => {
		console.log(9)
	})
	console.log(10)
</script> -->

<!-- <script>
	console.log(11)
	setTimeout(() => {
		console.log(12)
		let p = new Promise((resolve) => {
			resolve(13)
		})
		p.then((res) => {
			console.log(res)
		})
		console.log(15)
	}, 0)
	console.log(14)
</script> -->

<!-- 第六题字节面试 -->
<script>
	async function async1() {
		console.log('1')
		await async2()
		console.log('2')
	}

	async function async2() {
		console.log('3')
	}

	console.log('4')

	setTimeout(function () {
		console.log('5')
	}, 0)

	async1()

	new Promise(function (resolve) {
		console.log('6')
		resolve()
	}).then(function () {
		console.log('7')
	})

	console.log('8')
</script>

注意 :

1.script最先放到宏任务

2.注意setimeout的时间谁快谁先放入宏任务

3.多个script要一开始就连着排队

\

猜你喜欢

转载自blog.csdn.net/qq_52006046/article/details/128822784