大家经常听到js是一门单线程语言,即同一时间只能做同一事件,但为何他是单线程呢?多线程的执行效率不是更高吗?
js这门语言主要用途是操作DOM,这就决定了他只能是门单线程语言。可以试想一下,如果js为多线程,那同一时间对DOM进行删除操作,而又对其进行添加操作,此时此刻,浏览器引擎应该怎么处理呢?答案显而易见,浏览器难以抉择的,单线程的设计是为了避免DOM渲染等操作的冲突。
那么,既然js是单线程的,那它是如何去执行异步任务的呢?
js是靠浏览器内核去执行的,浏览器内核可以处理多线程。js通过回调函数来实现异步运行:
- 所有同步任务按顺序在主线程上执行,即形成一个执行栈
- 异步任务有运行结果就在任务队列中放置一个事件
- 先执行完执行栈中的同步任务,随后任务队列中与事件对应的异步任务结束等待,跑到执行栈中执行(任务队列先进先出)
- 重复3(事件轮询)
拓展:
事件轮询,同步任务放主线程(执行栈),异步任务放任务队列等待,待执行栈中同步任务执行完毕,将微任务压入执行栈中执行。微任务执行完毕,再执行宏任务队列。每次宏任务执行完毕,都会去判断微任务队列是否产生新任务,若存在就优先执行微任务,否则按序执行宏任务。(循环)任务队列可划分为宏任务队列和微任务队列,在任务队列中微任务执行先于宏任务。微任务常见:promise.then();宏任务常见:setTimeout、setInterval、I/O、script(整块代码)、网络请求(ajax)。