Node.js 事件循环与多进程

事件循环介绍

浏览器中的事件循环(Event loop)

为了协调事件,用户交互,脚本,渲染,网络等,用户代理必须使用事件循环。

  • 事件:PostMessage,MutationObserver 等
  • 用户交互: click,onScroll等
  • 渲染: 解析DOM,css等
  • 脚本: js脚本执行

    Javasc为什么是单线程的?

    浏览器js的作用时操作DOM,这决定了他只能是单线程,否则会带来很复杂的同步问题,比如假定Javasc同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

    任务队列

  • 单线程就意味着所有任务需要排队,如果因为任务CPU计算量大还好,但是I/O操作是闲着的,所以JS就设计成了一门异步的语言,不会做无畏的等待。任务可以分成两种,一种时同步任务,另一种是异步任务。
    • 所有同步任务都在主线程上执行,形成一个执行栈。
    • 主线程之外,还存在一个任务队列,只要异步任务有了运行结果,就在“任务队列”之中放置一个事件。
    • 一旦“执行栈”中的所有同步任务执行完毕,系统就会读取“任务队列”,看看里面有哪些事件,那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
    • 主线程不断重复上面的第三步。
      主线程从“任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop (事件循环)

宏任务与微任务

除了广义的同步任务和异步任务,JavaScript单线程中的任务可以细分为宏任务和微任务

  • macrotask宏任务: script(整体代码)setTimeout ,setInterval, setImmediate, I/O, UI reading
  • microtask微任务: process, nextTick,Promises, Object, Observer, MutationObserver
    • 宏任务进入主线程,执行过程中会收集微任务队列。
    • 宏任务执行完成之后,立马执行微任务中的任务,微任务执行过程中将再次收集宏任务,并加入宏任务队列。
    • 反复执行1,2步骤

执行顺序:一轮事件循环会执行一次宏任务以及所有微任务。

Node.js中的事件循环

事件循环允许Node.js执行非阻塞I/O操作,尽管JavaScript时单线程的,通过尽可能将操作卸载到系统内核。由于大多数现代内核都是多线程的,因此它们可以处理在后台执行的多个操作,当其中一个操作完成时,内核会告诉Node.js,以便可以将响应的回调添加到轮询队列中以最终执行。

  • 事件: Eventmitter
  • 非阻塞I/O: 网络请求,文件读写等。
  • 脚本: js脚本执行

事件循环的本质

在浏览器或者Node.js环境中,运行时对js脚本的调度方式就叫做事件循环。

猜你喜欢

转载自www.cnblogs.com/liea/p/11833371.html