深入了解事件循环(node和浏览器)

• 浏览器的事件循环是一个我们编写的javascript代码和浏览器api调用(Ajax/setTimeout)的一个桥梁,桥梁之间他们通过回调函数进行沟通
• Node的事件循环是javascript和系统调用之间的一个桥梁,桥梁之间他们通过会掉函数进行沟通
一、浏览器的事件循环

  1. 进程和线程
    • 进程(process):计算机已经运行的程序(启动一个应用后程序,默认启动一个进程,也可能是多个进程)
    • 线程(thread):操作系统能够运行运算调度的最小单位(每一个进程中,都会启动一个线程来执行程序中的代码,这个线程叫主线程)
    可以说,进程是线程的容器
    • 操作系统类似于一个工厂;
    • 工厂中里有很多车间,这个车间就是进程;
    • 每个车间可能有一个以上的工人在工厂,这个工人就是线程;
    2.浏览器和JavaScript
    • 我们经常会说JavaScript是单线程的,但是JavaScript的线程应该有自己的容器进程:浏览器或者Node。
    • 目前多数的浏览器都是多进程的,没打开一个tab页面就会开启一个新的进程,避免一个页面卡死所有页面无法响应,需要整个强制退出
    • 但是Javascript是在一个单独的线程中执行的 ,同一时刻只做一件事,如果这件事情非常耗时,就会被阻塞
    3.浏览器的事件循环
    同步函数调用 该函数会被放到调用栈中执行
    异步函数调用 该函数会被放到调用占中 执行立即结束,不会阻塞后续代码的执行
    4.宏任务和微任务
    事件循环中有两个队列
    • 宏任务队列 (ajax、setTimeout、setInterval/Dom监听)
    • 微任务队列 (Promise的then回调,Promise的then回调、process.nextTick、queueMicrotask;)
    两个队列的优先级
    执行每一个宏任务之前,都会查看微任务队列是否有任务需要执行
    也就是宏任务执行之前,必须保证微任务是空的
    async、await是Promise的一个语法糖:
    • 我们可以将await关键字后面执行的代码,看做是包裹在(resolve, reject) => {函数执行}中的代码;
    • await的下一条语句,可以看做是then(res => {函数执行})中的代码;
    二、Node的事件循环

• 无论是我们的文件IO、数据库、网络IO、定时器、子进程,在完成对应的操作后,都会将对应的结果和回调函数放到事件循环(任务队列)中;
• 事件循环会不断的从任务队列中取出对应的事件(回调函数)来执行;
• 微任务队列:
• next tick queue:process.nextTick;
• other queue:Promise的then回调、queueMicrotask;
• 宏任务队列:
• timer queue:setTimeout、setInterval;
• poll queue:IO事件;
• check queue:setImmediate;
• close queue:close事件;
所以,在每一次事件循环的tick中,会按照如下顺序来执行代码:
• next tick microtask queue;
• other microtask queue;
• timer queue;
• poll queue;
• check queue;
• close queue;

猜你喜欢

转载自blog.csdn.net/qq_41988554/article/details/114133256