当前位置: 首页 > news >正文

广州市公司网站建设品牌江苏强荣建设有限公司网站

广州市公司网站建设品牌,江苏强荣建设有限公司网站,建设专题网站,深圳微信商城网站设计价格你已经使用 Node.js 一段时间了#xff0c;构建了一些应用程序#xff0c;尝试了不同的模块#xff0c;甚至对异步编程感到很舒适。但是有些事情一直在困扰着你——事件循环#xff08;Event Loop#xff09;。 如果你像我一样#xff0c;花费了无数个小时阅读文档和观看…你已经使用 Node.js 一段时间了构建了一些应用程序尝试了不同的模块甚至对异步编程感到很舒适。但是有些事情一直在困扰着你——事件循环Event Loop。 如果你像我一样花费了无数个小时阅读文档和观看视频试图理解事件循环。但即使作为一个经验丰富的开发者在完全理解它如何工作方面也可能会遇到困难。这就是为什么我准备了这份视觉指南帮助您充分理解 Node.js 事件循环。请坐下来拿杯咖啡让我们深入探索 Node.js 事件循环的世界吧。 JavaScript 中的异步编程 我们将从 JavaScript 中异步编程的复习开始。虽然 JavaScript 在 Web、移动和桌面应用程序中都有使用但重要的是要记住本质上JavaScript 是一种同步、阻塞、单线程的语言。让我们通过一个简短的代码片段来理解这句话。 // index.jsfunction A() {console.log(A); }function B() {console.log(B); }A() B()// Logs A and then B JavaScript 是同步的 如果我们有两个将消息记录到控制台的函数那么代码会自上而下执行每次只执行一行。在上述代码片段中我们看到 A 在 B 之前被记录。 JavaScript 是阻塞的 JavaScript 由于其同步性质而被阻塞。无论前一个进程需要多长时间后续进程都不会启动直到前者完成为止。在代码片段中如果函数 A 必须执行大量代码块则 JavaScript 必须在没有转移到函数 B 的情况下完成该操作。即便这块代码需要耗时 10 秒甚至 1 分钟。 你可能已经在浏览器中遇到过这种情况。当 Web 应用程序在浏览器中运行并且执行一些密集的代码块而不返回控制权给浏览器时浏览器可能会出现卡死的情况这就是所谓的阻塞。浏览器被阻止继续处理用户输入和执行其他任务直到 Web 应用程序将处理器控制权归还给浏览器。 JavaScript 是单线程的 线程就是你的 JavaScript 程序可以用来运行任务的进程process。每个线程一次只能执行一个任务。与其他支持多线程并且可以同时运行多个任务的语言不同JavaScript 只有一个称为主线程的线程执行代码。 等待 JavaScript 如你所想这种 JavaScript 模型会带来问题因为我们必须等待数据被获取后才能继续执行代码。这个等待可能需要几秒钟在此期间我们无法运行任何其他代码。如果 JavaScript 在不等待的情况下继续处理就会出错。我们需要在 JavaScript 中实现异步行为。我们进到 Node.js 看一下。 Node.js 运行时 Node.js 运行时是一个环境你可以在不使用浏览器的情况下使用和运行 JavaScript 程序。核心——Node 运行时由三个主要组件组成。 外部依赖项 —— 例如 V8、libuv、crypto 等——是 Node.js 必需的功能C 特性提供了文件系统访问和网络等功能。JavaScript 库提供了函数和工具便于使用 JavaScript 代码调用 C 特性。 虽然所有部分都很重要但异步编程在 Node.js 中的关键组件是 libuv。 Libuv Libuv[2] 是一个跨平台的开源库用 C 语言编写。在 Node.js 运行时中它的作用是提供处理异步操作的支持。我们来看一下它是如何工作的。 Node.js 运行时中的代码执行 让我们来概括一下代码在 Node 运行时中的执行方式。在执行代码时位于图片左侧的 V8 引擎负责 JavaScript 代码的执行。该引擎包含一个内存堆Memory heap和一个调用栈Call stack。 每当声明变量或函数时都会在堆上分配内存。执行代码时函数就会被推入调用栈中。当函数返回时它就从调用栈中弹出了。这是对栈数据结构的简单实现最后添加的项是第一个被移除。在图片右侧是负责处理异步方法的 libuv。 每当我们执行异步方法时libuv 接管任务的执行。然后使用操作系统本地异步机制运行任务。如果本地机制不可用或不足则利用其线程池来运行任务并确保主线程不被阻塞。 同步代码执行 首先让我们来看一下同步代码执行。以下代码由三个控制台日志语句组成依次记录“First”“Second”和“Third”。我们按照运行时执行顺序来查看代码。 // index.js console.log(First); console.log(Second); console.log(Third); 以下是 Node 运行时执行同步代码的可视化展示。 执行的主线程始终从全局作用域开始。全局函数如果我们可以这样称呼它被推入堆栈中。然后在第 1 行我们有一个控制台日志语句。这个函数被推入堆栈中。假设这个发生在 1 毫秒时“First” 被记录在控制台上。然后这个函数从堆栈中弹出。 执行到第 2 行时。假设到第 2 毫秒了log 函数再次被推入堆栈中。“Second”被记录在控制台上并弹出该函数。 最后执行到第 3 行了。第 3 毫秒时log 函数被推入堆栈“Third”将记录在控制台上并弹出该函数。此时已经没有代码要执行全局也被弹出。 异步代码执行 接下来让我们看一下异步代码执行。有以下代码片段包含三个日志语句但这次第二个日志语句传递给了fs.readFile() 作为回调函数。 执行的主线程始终从全局作用域开始。全局函数被推入堆栈。然后执行到第 1 行在第 1 毫秒时“First”被记录在控制台中并弹出该函数。然后执行移动到第 2 行在第 2毫秒时readFile 方法被推入堆栈。由于 readFile 是异步操作因此它会转移off-loaded到 libuv。 JavaScript 从调用堆栈中弹出了 readFile 方法因为就第 2 行的执行而言它的工作已经完成了。在后台libuv 开始在单独的线程上读取文件内容。在第 3 毫秒时JavaScript 继续进行到第 5 行将 log 函数推入堆栈“Third”被记录到控制台中并将该函数弹出堆栈。 大约在第 4 毫秒左右假设文件读取任务已经完成则相关回调函数现在会在调用栈上执行 在回调函数内部遇到 log 函数。 log 函数推入到到调用栈“Second”被记录到控制台并弹出 log 函数 。由于回调函数中没有更多要执行的语句因此也被弹出 。没有更多代码可运行了 所以全局函数也从堆栈中删除 。 控制台输出“First”“Third”然后是“Second”。 Libuv 和异步操作 很明显libuv 用于处理 Node.js 中的异步操作。对于像处理网络请求这样的异步操作libuv 依赖于操作系统原生机制。对于没有本地 OS 支持的异步读取文件的操作libuv 则依赖其线程池以确保主线程不被阻塞。然而这也引发了一些问题。 当一个异步任务在 libuv 中完成时什么时候 Node 会在调用栈上运行相关联的回调函数Node 是否会等待调用栈为空后再运行回调函数还是打断正常执行流来运行回调函数像 setTimeout 和 setInterval 这类延迟执行回调函数的方法又是何时执行回调函数呢如果 setTimeout 和 readFile 这类异步任务同时完成Node 如何决定哪个回调函数先在调用栈上运行其中一个会有更多的优先级吗 所有这些问题都可以通过理解 libuv 核心部分——事件循环来得到答案。 什么是事件循环 从技术上讲事件循环只是一个 C 语言程序。但是在 Node.js 中你可以将其视为一种设计模式用于协调同步和异步代码的执行。 可视化事件循环 事件循环是一个循环只要你的 Node.js 应用程序在运行它就一直运行。每个循环中有六个不同的队列每个队列都包含一个或多个需要最终在调用堆栈上执行的回调函数。 首先有一个计时器队列timer queue。技术上叫最小堆min-heap它保存与 setTimeout 和 setInterval 相关的回调函数。其次有一个 I/O 队列I/O queue其中包含与所有异步方法相关的回调函数例如 fs 和 http 模块中提供的相关方法。第三个是检查队列check queue它保存与 setImmediate 函数相关的回调函数这是特定于Node 的功能。第四个是关闭队列close queue它保存与异步任务关闭事件相关联的回调函数。 最后有两个不同队列组成微任务队列microtask queue。 nextTick 队列保存了与 process.nextTick 函数关联的回调函数。Promise 队列则保存了JavaScript 中本地 Promise 相关联的回调函数。 需要注意的是计时器、I/O、检查和关闭队列都属于 libuv。然而两个微任务队列并不属于 libuv。尽管如此它们仍然是 Node 运行时环境中扮演着重要角色并且在执行回调顺序方面发挥着重要作用。说到这里, 让我们来理解一下事件循环是如何工作的。 事件循环是如何工作的 图中箭头是一个提示但可能还不太容易理解。让我来解释一下队列的优先级顺序。首先要知道所有用户编写的同步 JavaScript 代码都比异步代码优先级更高。这表示只有在调用堆栈为空时事件循环才会发挥作用。 在事件循环中执行顺序遵循某些规则。需要掌握的规则还是有一些的我们逐个的了解一下 执行微任务队列microtask queue中的所有回调函数。首先是 nextTick 队列中的任务然后是 Promise 队列中的任务。执行计时器队列timer queue内的所有回调函数。如果微任务队列中存在回调函数则在计时器队列内每执行完一次回调函数之后执行微任务队列中的所有回调函数。首先是 nextTick 队列中的任务然后是 Promise 队列中的任务。执行 I/O 队列I/O queue内的所有回调函数。如果微任务队列中存在回调函数按照先 nextTick 队列后 Promise 队列的顺序依次执行微任务队列中的所有回调函数。执行检查队列check queue内的所有回调函数。如果微任务队列中存在回调函数则在检查队列内每个回调之后执行微任务队列中的所有回调函数 。首先是 nextTick 队列中的任务然后是 Promise 队列中的任务。执行关闭队列close queue内的所有回调函数。在同一循环的最后再执行一次微任务队列。首先是 nextTick 队列中的任务然后是 Promise 队列中的任务。 此时如果还有更多的回调需要处理那么事件循环再运行一次译注事件循环在程序运行期间一直在运行在当前没有可供处理的任务情况下会处于等待状态一旦有新任务就会执行并重复相同的步骤。另一方面如果所有回调都已执行并且没有更多代码要处理译注也就是程序执行结束则事件循环退出。 这就是 libuv 事件循环在 Node.js 中执行异步代码的作用。有了这些规则我们可以重新审视之前提出的问题。 当一个异步任务在 libuv 中完成时什么时候 Node 会在调用栈上运行相关联的回调函数 答案只有当调用栈为空时才执行回调函数。 Node 是否会等待调用栈为空后再运行回调函数还是打断正常执行流来运行回调函数 答案运行回调函数时不会打断正常执行流。 像 setTimeout 和 setInterval 这类延迟执行回调函数的方法又是何时执行回调函数呢 答案*setTimeout 和 setInterval 的所有回调函数中第一优先级执行的不考虑微任务队列。* 如果两个异步任务例如 setTimeout 和 readFile同时完成Node 如何决定那个回调函数先在调用栈中执行其中一个会比另一个有更高优先权吗 答案在同时完成的情况下计时器回调会先于 I/O 回调执行。 到此为止我们学了很多但我希望大家可以把下面这张图片展现的执行顺序铭记于心因为它完整的表现了 Node.js 在幕后是如何执行异步代码的。 结论 事件循环是 Node.js 的基本组成部分通过确保主线程不被阻塞来实现异步编程。了解事件循环的工作原理可能具有挑战性但对于构建高效应用程序至关重要。 这个视觉指南涵盖了 JavaScript 中异步编程、Node.js 运行时和负责处理异步操作的 libuv 的基础知识。有了这些知识你可以建立一个强大的事件循环模型在编写利用 Node.js 异步特性的代码时受益。 参考资料 [1]A Complete Visual Guide to Understanding the Node.js Event Loop:https://www.builder.io/blog/visual-guide-to-nodejs-event-loop [2]Libuv:https://libuv.org/
http://www.hkea.cn/news/14529719/

相关文章:

  • 做网站时给网页增加提醒潍坊百度seo公司
  • 给网站加织梦后台小广告治理
  • 网站建设嘉兴wordpress更换主题帖子封面不显示
  • 做网站上哪买空间平湖建设局网站
  • 深圳微商城网站设计制作wordpress添加注册页面模板
  • 织梦做的网站怎么发布杭州公司建网站
  • 揭阳网站制作机构可编辑wordpress主题
  • 大兴网站制作青海建设厅网站尚少岩
  • 赣州网站建设怎样晋江论坛网友交流留言区
  • 三星网站建设内容爱情动做网站推荐
  • 手机网站APP网络推广商城网站社群运营
  • 详情页设计模板网站门户网站都有哪些内容
  • 做旅游网站的yi鲜花网页设计模板
  • 地域名网址ip查询团购网站如何优化
  • 网站建设方案书域名备案菏泽网站建设
  • 网站 wap 插件婚恋网站女孩子都是做美容
  • 寿光网站建设推广大连金州代做网站公众号
  • 外国永久网站广州建筑集团网站
  • 南昌网站定制phpcms做视频网站
  • dedecms游戏门户网站源码卓手机建网站
  • 整人关不掉的网站怎么做虚拟机怎么做多个网站
  • 图片链接生成网站宜城网站建设哪家好
  • 中国水利教育培训网站选择网站建设公司好
  • 网站建设和执纪监督怎么联系地推公司
  • 邢台移动网站建设价格郴州建设工程建设信息网站
  • 中山市网站开发外包公司全国前十装饰公司排名
  • 郑州汉狮专业做网站公司dede导入wordpress
  • 龙岗建网站公司齐鲁人才网招聘网
  • 技术网站摄影网页设计方案
  • 上海共富新村网站建设wordpress超联系