一、什么是单线程?
首先我们要知道什么是线程,线程是包含在进程中的,是进程中的实际运作单位,一个进程可以有一个或多个线程同时进行工作,相互不影响。
而所谓单线程是指在一个进程中只开一个线程,也就是只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推
(进程可以看作是一个工厂,工厂有它的独立资源,工厂之间相互独立线程是工厂中的工人,多个人协作完成任务,工厂内有一个或多个工人,工人之间共享空间。如果工厂中有多个工人,我们称之为多线程如果工厂中只有一个工人,我们称之为单线程)
二、JS问什么是单线程?
“JS是单线程主要于他的用途有关,JS主要就是用来与用户交互,操作DOM”
(比如说我们给一个DOM元素同时进行了添加与删除操作,两种操作不能同时进行,应该先进行添加之后在删除)单线程意味着所有任务都需要排队,前一个任务执行结束,才会执行后一个任务。
三、单线程所带来的问题
因为单线程原理就是要前一个任务执行结束后才会执行下一个任务,但是前一个任务如果执行事件过长,就会导致后面的任务一直无法进行(如果js执行时间过长,就会导致页面渲染不连贯,导致页面加载阻塞)
四、同步任务与异步任务
1.同步任务
同步任务就是指从上至下按照顺序一步步的执行程序,在"主线程"上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
2.异步任务
异步任务指的是,不进入主线程、而进入"任务队列"的任务,只有"任务队列""通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
(异步就好比你在做一件事情时,因为这件事情会花费很长时间,在做件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。)
五、JS为什么需要异步,如何处理异步任务
1.JS为什么需要异步
因为JS是单线程,如果没有异步,所有程序就必须按照顺序一个个去执行,如果一个任务的执行事件非常长,就会导致”阻塞“,使后面的任务,也就会导致页面渲染不流畅,而异步可以解决JS单线程所带来的问题。
2.如果处理异步任务
JS代码处理任务主要依赖于任务队列和事件循环
- 任务队列:任务队列是一个先进先出的队列,它里面存放着各种任务。
- 事件循环:事件循环是指主线程重复从任务队列中取任务、执行任务的过程。
首先js代码会判断代码是同步还是异步,同步就进入主线程,如果是异步会判断是否满足触发条件,在满足触发条件后会被放进任务队列只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
(比如说click事件与定时器setTimeout ,在click事件没有被触发也就是没有被点击的时候它是并没不会进入任务队列的,定时器也一样,定时器在没有达到指定秒数的时候也不会被推进任务队列中)
比如:
console.log(4);
setTimeout(function() {
console.log(1);
})
console.log(2);
console.log(3);
输出结果为4231,423为同步任务,会先按照顺序执行,执行完毕完毕之后会去找异步任务,此时发现任务队列中有setTimeout,这时才会将setTimeout放进主线程中执行,如果setTimeout设置的时间过长,也不会影响后面的同步任务执行,等setTimeout时间到了触发了之后,才会执行它
六、异步任务有哪些
事件绑定和定时器都为异步任务
setTimeout setInterval click mouseenter focus blur等
七、微任务,宏任务
异步任务又分微任务 ,宏任务
宏任务: setTimeout、setInterval等,会被放在宏任务(macrotask)队列
微任务: Promise的then、Mutation Observer等,会被放在微任务(microtask)队列
首先执行同步任务,同步任务执行完毕之后去找微任务,微任务全部执行完在找宏任务
微任务队列每次全执行,宏任务队列每次只取一项执行