对容器、虚拟机和 Docker 的初学者友好介绍
一、说明
如果你是一个程序员或技术人员,你可能至少听说过Docker:一个有用的工具,用于在“容器”中打包,运输和运行应用程序。很难不这样做,这些天它得到了所有的关注 - 来自开发人员和系统管理员。即使是像谷歌、VMware和亚马逊这样的大型企业也在构建支持它的服务。
无论您是否对 Docker 有直接的用例,我仍然认为了解“容器”是什么以及它与虚拟机 (VM) 的比较的一些基本概念非常重要。虽然互联网上到处都是 Docker 的优秀使用指南,但我找不到很多适合初学者的概念指南,尤其是关于容器的组成。所以,希望这篇文章能解决这个问题:)
让我们从了解什么是虚拟机和容器开始。
二、什么是“容器”和“虚拟机”?
容器和虚拟机的目标相似:将应用程序及其依赖项隔离到可在任何位置运行的独立单元中。
此外,容器和虚拟机消除了对物理硬件的需求,从而在能耗和成本效益方面更有效地利用计算资源。
容器和虚拟机之间的主要区别在于它们的体系结构方法。让我们仔细看看。
2.1 虚拟机
VM 本质上是对真实计算机的仿真,它像真实计算机一样执行程序。VM 使用“虚拟机监控程序”在物理机上运行。反过来,虚拟机监控程序在主机或“裸机”上运行。
让我们解开行话:
虚拟机监控程序是 VM 在其上运行的软件、固件或硬件。虚拟机管理程序本身在物理计算机上运行,称为“主机”。主机为 VM 提供资源,包括 RAM 和 CPU。这些资源在 VM 之间分配,可以根据需要进行分配。因此,如果一个 VM 正在运行资源量更大的应用程序,则与在同一主机上运行的其他 VM 相比,您可以为该 VM 分配更多的资源。
在主机上运行的 VM(同样,使用虚拟机监控程序)通常也称为“来宾计算机”。此来宾计算机包含应用程序以及运行该应用程序所需的任何内容(例如系统二进制文件和库)。它还拥有自己的整个虚拟化硬件堆栈,包括虚拟化网络适配器、存储和 CPU,这意味着它还拥有自己成熟的来宾操作系统。从内部看,来宾计算机充当自己的单元,具有自己的专用资源。从外部,我们知道它是一个虚拟机 - 共享主机提供的资源。
如上所述,来宾计算机可以在托管虚拟机管理程序或裸机虚拟机管理程序上运行。它们之间存在一些重要差异。
首先,托管虚拟化虚拟机管理程序在主机的操作系统上运行。例如,运行OSX的计算机可以在该操作系统上安装VM(例如VirtualBox或VMware Workstation 8)。虚拟机无法直接访问硬件,因此它必须通过主机操作系统(在本例中为 Mac 的 OSX)。
托管虚拟机管理程序的好处是底层硬件不太重要。主机的操作系统负责硬件驱动程序而不是虚拟机管理程序本身,因此被认为具有更多的“硬件兼容性”。另一方面,硬件和虚拟机管理程序之间的这一额外层会产生更多的资源开销,从而降低 VM 的性能。
裸机虚拟机管理程序环境通过在主机硬件上安装并从中运行来解决性能问题。由于它直接与底层硬件接口,因此不需要主机操作系统即可运行。在这种情况下,作为操作系统安装在主机服务器上的第一件事将是虚拟机监控程序。与托管虚拟机监控程序不同,裸机虚拟机监控程序具有自己的设备驱动程序,并直接与每个组件交互以执行任何 I/O、处理或特定于操作系统的任务。这样可以提高性能、可伸缩性和稳定性。这里的权衡是硬件兼容性有限,因为虚拟机管理程序只能内置这么多设备驱动程序。
在讨论了虚拟机管理程序之后,您可能想知道为什么我们需要在虚拟机和主机之间增加这个“虚拟机管理程序”层。
由于虚拟机有自己的虚拟操作系统,因此虚拟机管理程序在为 VM 提供管理和执行此来宾操作系统的平台方面起着至关重要的作用。它允许主机计算机在作为来宾运行的虚拟机之间共享其资源。
虚拟机关系图
如图所示,虚拟机为每个新虚拟机打包了虚拟硬件、内核(即操作系统)和用户空间。
2.2 容器
与提供硬件虚拟化的 VM 不同,容器通过抽象“用户空间”来提供操作系统级虚拟化。当我们解开容器一词时,您将明白我的意思。
出于所有意图和目的,容器看起来像一个 VM。例如,它们具有用于处理的私有空间,可以以root身份执行命令,具有专用网络接口和IP地址,允许自定义路由和iptable规则,可以挂载文件系统等。
容器和虚拟机之间的一个很大区别是容器与其他容器*共享*主机系统的内核。

此图显示容器仅打包用户空间,而不是像 VM 那样打包内核或虚拟硬件。每个容器都有自己的独立用户空间,以允许多个容器在单个主机上运行。我们可以看到,所有操作系统级别的架构都在容器之间共享。从头开始创建的唯一部分是垃圾箱和库。这就是使容器如此轻巧的原因。
2.3 Docker从何而来?
Docker是一个基于Linux容器的开源项目。它使用 Linux 内核功能(如命名空间和控制组)在操作系统之上创建容器。
容器远非新鲜事物;谷歌多年来一直在使用自己的容器技术。其他Linux容器技术包括Solaris Zones,BSD监狱和LXC,它们已经存在了很多年。
那么,为什么Docker突然变得火了呢?
1. 易用性:Docker 使任何人(开发人员、系统管理员、架构师和其他人)都更容易利用容器来快速构建和测试可移植应用程序。它允许任何人在他们的笔记本电脑上打包应用程序,而这些应用程序又可以在任何公共云、私有云甚至裸机上未经修改地运行。口头禅是:“一次构建,随处运行。
2.速度:Docker容器非常轻巧和快速。由于容器只是在内核上运行的沙盒环境,因此它们占用的资源更少。您可以在几秒钟内创建和运行 Docker 容器,相比之下,VM 可能需要更长的时间,因为它们每次都必须启动完整的虚拟操作系统。
3. Docker Hub:Docker 用户还受益于 Docker Hub 日益丰富的生态系统,您可以将其视为“Docker 镜像的应用商店”。Docker Hub 拥有数以万计由社区创建的公共镜像,随时可供使用。搜索满足您需求的图像非常容易,几乎无需修改即可下拉和使用。
4. 模块化和可扩展性:Docker 可以轻松地将应用程序的功能分解为单独的容器。例如,您可能将 Postgres 数据库运行在一个容器中,将 Redis 服务器运行在另一个容器中,而 Node.js 应用程序在另一个容器中运行。借助 Docker,可以更轻松地将这些容器链接在一起以创建应用程序,从而在将来轻松独立扩展或更新组件。
最后但并非最不重要的一点是,谁不喜欢码头工人鲸?;)
来源: Docker: Accelerated Container Application Development
三、基本码头工人概念
现在我们已经了解了大局,让我们逐一介绍 Docker 的基本部分:

3.1 码头工人引擎
Docker 引擎是 Docker 运行的层。它是一个轻量级运行时和工具,用于管理容器、映像、生成等。它在 Linux 系统上本机运行,由以下部分组成:
1. 在主机中运行的 Docker 守护程序。
2. 一个 Docker 客户端,然后与 Docker 守护程序通信以执行命令。
3. 用于与 Docker 守护进程远程交互的 REST API。
3.2 码头工人客户端
作为 Docker 的最终用户,Docker 客户端是与之通信的对象。可以将其视为 Docker 的 UI。例如,当您执行...
您正在与 Docker 客户端通信,然后 Docker 客户端将您的指令传达给 Docker 守护程序。
3.3 码头工人守护进程
Docker 守护程序是实际执行发送到 Docker 客户端的命令,例如构建、运行和分发容器。Docker 守护程序在主机上运行,但作为用户,您从不直接与守护程序通信。Docker 客户端也可以在主机上运行,但不是必需的。它可以在不同的计算机上运行,并与主机上运行的 Docker 守护程序进行通信。
3.4 Dockerfile
Dockerfile 是您编写构建 Docker 映像的说明的地方。这些说明可以是:
- 运行 apt-get y install some-package: 安装软件包
- 公开 8000:公开端口
- ENV ANT_HOME /usr/local/apache-ant 来传递环境变量
等等。设置 Dockerfile 后,可以使用 docker build 命令从中构建映像。下面是一个 Dockerfile 的示例:
示例 Dockerfile
3.5 码头工人镜像
映像是根据 Dockerfile 中编写的一组指令构建的只读模板。映像定义您希望打包的应用程序及其依赖项的外观,以及启动时要运行的进程。
Docker 镜像是使用 Dockerfile 构建的。Dockerfile 中的每个指令都会向映像添加一个新“层”,其中层表示映像文件系统的一部分,该部分添加或替换其下方的层。层是 Docker 轻巧而强大的结构的关键。Docker 使用联合文件系统来实现这一点:
3.6 联合文件系统
Docker 使用联合文件系统来构建映像。您可以将联合文件系统视为可堆叠的文件系统,这意味着可以透明地覆盖单独文件系统(称为分支)的文件和目录以形成单个文件系统。
在覆盖分支中具有相同路径的目录的内容被视为单个合并目录,从而避免了为每个层创建单独副本的需要。相反,它们可以都被赋予指向同一资源的指针;当某些图层需要修改时,它将创建一个副本并修改一个本地副本,保持原始副本不变。这就是文件系统在实际上不允许写入的情况下*看起来*可写的方式。(换句话说,“写入时复制”系统。
分层系统有两个主要优点:
1. 无重复:层有助于避免每次使用映像创建和运行新容器时复制一组完整的文件,从而使 docker 容器的实例化非常快速和便宜。
2. 层隔离:进行更改要快得多 — 当您更改映像时,Docker 只会将更新传播到已更改的层。
3.7 卷
卷是容器的“数据”部分,在创建容器时初始化。卷允许您保留和共享容器的数据。数据卷独立于默认的联合文件系统,并作为普通目录和文件存在于主机文件系统上。因此,即使销毁、更新或重建容器,数据卷也不会受到影响。当您想要更新卷时,您可以直接对其进行更改。(作为额外的好处,数据量可以在多个容器之间共享和重用,这非常整洁。
3.8 码头工人容器
如上所述,Docker 容器将应用程序的软件包装到一个不可见的盒子中,其中包含应用程序运行所需的一切。这包括操作系统、应用程序代码、运行时、系统工具、系统库等。Docker 容器基于 Docker 镜像构建。由于镜像是只读的,Docker 会在镜像的只读文件系统上添加读写文件系统来创建容器。

此外,在创建容器时,Docker 会创建一个网络接口,以便容器可以与本地主机通信,将可用的 IP 地址附加到容器,并执行您在定义映像时指定用于运行应用程序的进程。
成功创建容器后,可以在任何环境中运行它,而无需进行更改。
四、双击“容器”
唷!这是很多活动部件。总是让我好奇的一件事是容器是如何实际实现的,特别是因为容器周围没有任何抽象的基础设施边界。经过大量阅读,这一切都是有道理的,所以这是我尝试向您解释的尝试!:)
术语“容器”实际上只是一个抽象的概念,用于描述几个不同的功能如何协同工作以可视化“容器”。让我们快速浏览一下它们:
4.1 命名空间
命名空间为容器提供了自己的底层 Linux 系统视图,从而限制了容器可以看到和访问的内容。运行容器时,Docker 会创建特定容器将使用的命名空间。
Docker 在内核中使用了几种不同类型的命名空间,例如:
a. NET:为容器提供自己的系统网络堆栈视图(例如,它自己的网络设备、IP 地址、IP 路由表、/proc/net 目录、端口号等)。
b. PID:PID 代表进程 ID。如果您曾经在命令行中运行过ps aux来检查系统上正在运行的进程,那么您会看到一个名为“PID”的列。PID 命名空间为容器提供了自己的进程范围视图,这些进程可以查看并与之交互,包括独立的 init (PID 1),它是“所有进程的祖先”。
c. MNT:为容器提供自己的系统“挂载”视图。因此,不同挂载命名空间中的进程具有不同的文件系统层次结构视图。
d. UTS:UTS 代表 UNIX 分时系统。它允许一个过程来识别系统标识符(即主机名、域名等)。UTS 允许容器拥有独立于其他容器和主机系统的主机名和 NIS 域名。
e. IPC:IPC 代表进程间通信。IPC 命名空间负责在每个容器内运行的进程之间隔离 IPC 资源。
f. USER:此命名空间用于隔离每个容器中的用户。它的工作原理是允许容器具有与主机系统不同的 uid(用户 ID)和 gid(组 ID)范围视图。因此,进程的 uid 和 gid 在用户命名空间内部和外部可能不同,这也允许进程在容器外部拥有非特权用户,而不会牺牲容器内的根特权。
Docker 将这些命名空间一起使用,以便隔离并开始创建容器。下一个功能称为控制组。
4.2 控制组
控制组(也称为 cgroups)是一种 Linux 内核功能,用于隔离一组进程的资源使用情况(CPU、内存、磁盘 I/O、网络等),并确定其优先级并考虑其使用情况。从这个意义上说,cgroup 确保 Docker 容器只使用它们需要的资源——如果需要,可以对容器*可以使用的资源设置限制。Cgroups还确保单个容器不会耗尽其中一个资源并导致整个系统瘫痪。
最后,联合文件系统是Docker使用的另一个功能:
4.3 隔离联合文件系统:
如上文 Docker 映像部分所述:)
这就是 Docker 容器的全部内容(当然,魔鬼在于实现细节——比如如何管理各个组件之间的交互)。
五、Docker的未来:Docker和VM将共存
虽然Docker肯定会获得很大的动力,但我不相信它会成为对虚拟机的真正威胁。 容器将继续取得进展,但有许多用例仍然更适合虚拟机。
例如,如果需要在多个服务器上运行多个应用程序,则使用 VM 可能是有意义的。另一方面,如果您需要运行单个应用程序的多个*副本*,Docker提供了一些引人注目的优势。
此外,虽然容器允许您将应用程序分解为功能更强大的离散部分以创建关注点分离,但这也意味着需要管理越来越多的部分,这可能会变得笨拙。
安全性也是Docker容器关注的一个领域 - 由于容器共享相同的内核,因此容器之间的屏障更薄。虽然完整 VM 只能向主机虚拟机监控程序发出超级调用,但 Docker 容器可以对主机内核进行系统调用,这会为攻击创建更大的外围应用。当安全性特别重要时,开发人员可能会选择虚拟机,这些虚拟机被抽象的硬件隔离,这使得相互干扰变得更加困难。
当然,随着容器在生产中获得更多曝光和用户的进一步审查,安全性和管理等问题肯定会发生变化。就目前而言,关于容器与虚拟机的争论最好是每天生活和呼吸它们的开发人员运营人员!
六、结论
我希望你现在具备了学习更多关于Docker的知识,甚至有一天可以在项目中使用它。与往常一样,如果我犯了任何错误或无论如何都可以提供帮助,请在评论中给我留言!
普雷蒂·卡西雷迪
相关文章:

对容器、虚拟机和 Docker 的初学者友好介绍
一、说明 如果你是一个程序员或技术人员,你可能至少听说过Docker:一个有用的工具,用于在“容器”中打包,运输和运行应用程序。很难不这样做,这些天它得到了所有的关注 - 来自开发人员和系统管理员。即使是像谷歌、VMwa…...
linux部署clickhouse(单机)
一、下载安装 1.1、下载地址 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区阿里巴巴开源镜像站,免费提供Linux镜像下载服务,拥有Ubuntu、CentOS、Deepin、MongoDB、Apache、Maven、Composer等多种开源软件镜像源,此外还提供域名解析DNS、…...
vue组件注册
组件注册分为全局注册和局部注册 全局注册 在 main.js 或者入口文件中 import { createApp } from vue; import MyComponent from ./components/MyComponent.vue;const app createApp();app.component(my-component, MyComponent);app.mount(#app); 我们首先通过createApp…...

day20 飞机大战射击游戏
有飞行物类 飞行 爆炸 的连环画, 飞行的背景图 , 子弹图, 还有游戏开始 暂停 结束 的画面图。 设计一个飞机大战的小游戏, 玩家用鼠标操作hero飞行机, 射出子弹杀死敌机,小蜜蜂。 敌机可以获得分数&…...

iOS设计规范是什么?都有哪些具体规范
iOS设计规范是苹果为移动设备操作系统iOS制定的设计指南。iOS设计规范的制定保证了苹果应用在外观和操作上的一致性和可用性,从而提高了苹果界面设计的用户体验和应用程序的成功性。本文将从七个方面全面分析iOS设计规范。 1.iOS设计规范完整版分享 由「即时设计」…...

动手学深度学习-pytorch版本(二):线性神经网络
参考引用 动手学深度学习 1. 线性神经网络 神经网络的整个训练过程,包括: 定义简单的神经网络架构、数据处理、指定损失函数和如何训练模型。经典统计学习技术中的线性回归和 softmax 回归可以视为线性神经网络 1.1 线性回归 回归 (regression) 是能为一个或多个…...

Spark 图计算ONEID 进阶版
0、环境信息 本文采用阿里云maxcompute的spark环境为基础进行的,搭建本地spark环境参考搭建Windows开发环境_云原生大数据计算服务 MaxCompute-阿里云帮助中心 版本spark 2.4.5,maven版本大于3.8.4 ①配置pom依赖 详见2-1 ②添加运行jar包 ③添加配置信…...

Comparable和Comparator区别
Comparable和Comparator接口都是实现集合中元素的比较、排序的,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。总体来讲&#x…...
JAVA知识点梳理
我的博客:lcatake_flume,spark,zookeeper-CSDN博客 看不懂的话进去看看 1.Java的三个版本 JAVASE 基本 JAVAME 微缩 JAVAEE 标准 3.java的特点 面向对象 跨平台:jvm将java文件转变为字节码文件(.class)在多个系统中运 行字…...

[SWPUCTF 2022 新生赛]ez_ez_php
这段代码是一个简单的PHP文件处理脚本。让我们逐行进行分析: error_reporting(0); - 这行代码设置了错误报告的级别为0,意味着不显示任何错误。 if (isset($_GET[file])) { - 这行代码检查是否存在一个名为"file"的GET参数。 if ( substr($_…...

GraphQL strawberry的使用回顾和体会
GraphQL vs RESTful 简单来说GraphQL 比起 RESTful 集成额外一些功能 出入参校验、序列化 (简化后端编程)自由可选的返回数据字段 (简化一些多余接口开发和沟通联调成本) 这些都是优点了。 开发效率在项目初期是很重要的,需要快速原型化。 但是后期稳定后&#…...
08无监督学习——聚类
1.什么是聚类任务? 类别:无监督学习 目的:通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的数据分析提供基础。 1.1K均值聚类 步骤: 随机选取样本作为初始均值向量(初始值:k的值【即几个簇】)分别…...
Python使用OpenCV库对彩色图像进行通道分离
目录 1、解释说明: 2、使用示例: 3、注意事项: 1、解释说明: 在Python中,我们可以使用OpenCV库对彩色图像进行通道分离。通道分离是将彩色图像的每个像素分解为三个通道(红、绿、蓝)的过程。…...
前端面试:【CSS】盒模型、选择器、布局、响应式设计、Flexbox 与 Grid
CSS(层叠样式表)是用于控制网页外观和布局的重要语言。在这篇文章中,我们将深入探讨CSS的基础知识,包括盒模型、选择器、布局、响应式设计,以及弹性盒子(Flexbox)和网格布局(Grid&am…...
深入浅出通过PHP封装根据商品ID获取抖音商品详情数据方法
抖音商城商品详情数据是指商品在抖音商城中的展示信息,包括商品的标题、描述、价格、图片等。商家可以通过商品详情数据了解用户对商品的兴趣和需求,从而进行优化和调整。 商品详情数据还可以帮助商家评估商品的销售情况和市场竞争力,为制定…...

排序(七种排序)
1.插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 6.快速排序 7.归并排序 1.插入排序 1.1思路 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列 1.2实现 //插入排…...

【工程优化问题】基于鲸鱼、萤火虫、灰狼优化算法的张力、压缩弹簧设计问题研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
sap ui5刷新页面的方式
1.第一种 window.location.reload();2.第二种 如果你想在UI5应用程序中使用MVC模式来处理页面刷新,可以通过重新加载当前路由来实现刷新。首先,确保你有一个Router对象实例: var oRouter = sap.ui.core.UIComponent.getRouterFor(this);然后&...
Java课题笔记~ Fastjson 概述
3.3 JSON串和Java对象的相互转换 学习完 json 后,接下来聊聊 json 的作用。 以后我们会以 json 格式的数据进行前后端交互。前端发送请求时,如果是复杂的数据就会以 json 提交给后端;而后端如果需要响应一些复杂的数据时,也需要…...

Arduino 入门学习笔记11 读写内置EEPROM
Arduino 入门学习笔记11 使用I2C读写EEPROM 一、Arduino 内置EEPROM介绍二、EEPROM 操作1. 包含EEPROM库:2. 写入数据到EEPROM:3. 从EEPROM读取数据4. 完整示例: 一、Arduino 内置EEPROM介绍 Arduino的内置EEPROM(Electrically E…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...