1.浏览器中的JavaScript线程
01.通常每个电脑存在多个进程,每个运行的程序是一个进程或多个进程(如QQ是一个进程),而一个进程中运行至少一个线程,我们常说JavaScript是单线程的,但是JavaScript的线程应该有自己的容器进程:浏览器或者Node,由于JavaScript是单线程的,意味着在同一时间只能做同一件事,如果这件事很耗时间,就意味着当前线程会被阻塞。真正耗时的操作实际上并不是由JavaScript线程来执行的,由于浏览器的每个进程是多线程的,可以由其他线程完成这个耗时的操作,比如网络请求、定时器等,我们只需要在特定的时候执行应该有的回调即可。
2.浏览器的事件循环
01.认识事件循环
(1).JavaScript线程执行代码时,会维护一个队列queue(先进先出),这个队列默认没有数据。在js代码中如果遇到异步代码(如setTimeout, Promise等),会把异步函数放入队列中,事件循环是指由js线程发起,在其他线程中计时,到了规定时间则把函数放入队列中,js线程会把队列中的数据取出来,如此反复执行的过程,就称为事件循环。
02.宏任务和微任务
(1)在js代码中如果遇到异步代码时,会根据具体的异步代码存入到队列queue中的宏任务队列(macrotask queue)或微任务队列(microtask queue),像定时器、ajax、DOM的点击事件等都是在宏任务队列中,而queueMicrotask、Promise的then、MutationObserver的API等会加入到微任务队列中的,在js规范中,在执行任何的宏任务之前,都需要先保证微任务已经清空了,如果不为空,就优先执行微任务。