进程和线程

进程:相当于是一个程序,一个进程可以有多个线程,如浏览器打开一个页面就是开辟一个进程
线程:具体的做事的。如浏览器一个页面会分配多个线程。
GUI渲染线程:自上而下渲染页面
HTTP网络请求线程:加载资源文件以及数据
JS渲染引擎线程【主线程】:JS是单线程的就是因为浏览器只会分配一个线程来执行JS代码
定时器监听线程:监听定时器是否到时间
DOM事件监听线程:监听DOM事件触发
… …

同步异步编程

同步:一件事一件事的做完,上一件事没有完成,后面的事情不会去做
异步:上一件事没有做完,后续的事情会继续去做

JS中的异步任务

异步宏任务:
定时器
HTTP网络请求
事件触发
… …
异步微任务:
promise.then()中的回调
aysnc方法中await后面的代码(generator)
requestAnimationFrame

事件循环机制[EventLoop]

主线程同步代码同步代码执行会在栈中开辟一个事件队列【EventQueue】,包含宏任务[Macro task]和微任务[Micro task]队列
碰到异步微任务或者异步宏任务会将其放到事件队列中对应的任务中
当同步代码执行完成空闲后,从任务队列中去取出任务开始执行
1、先找异步微任务[谁先放置],达到可执行【如promise.then中的回调函数,需要promise的状态变成了onfullield/onrejected状态才是可执行的状态】的微任务,就拿出来执行,直到任务队列中没有需要执行的再去异步宏任务中找
2、如果有多个任务都符合了可执行条件,则谁先到达先执行【如定时器,谁先到达等待时间谁先执行】
3、把需要执行的异步任务也拿到执行环境栈中,让主线程去执行

1.png

EventLoop示例

1、关于定时器可执行的示例:

  1. setTimeout(() => {
  2. console.log(1);
  3. }, 20);
  4. console.log(2);
  5. setTimeout(() => {
  6. console.log(3);
  7. }, 10);
  8. console.log(4);
  9. // console.time('AA');
  10. for (let i = 0; i < 90000000; i++) {
  11. // do soming
  12. }
  13. // 在执行完for循环后,前面两个定时器已经到达时间,并且3比1的定时器要先到达,所以先打印出来3
  14. //=>AA: 79ms 左右
  15. // console.timeEnd('AA');
  16. console.log(5);
  17. setTimeout(() => {
  18. console.log(6);
  19. }, 8);
  20. console.log(7);
  21. setTimeout(() => {
  22. console.log(8);
  23. }, 15);
  24. console.log(9);

2.png
2、如果碰到死循环的情况下,是由于死循环将主线程一直占用,导致后续代码不能继续向下执行
3.png
3、带有Promise的异步微任务
3.png4、带有async/await
1.png