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

在nodejs常见的不良做法及其优化解决方案

在nodejs常见的不良做法及其优化解决方案

当涉及到在expressnodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。

在本文中,我们将探索开发人员经常遇到的几种常见的错误做法,并通过代码示例研究优化的最佳做法,以纠正这些错误。

在本文的结尾,我们将清楚地了解如何避免这些错误并采用最佳最佳实践。

嵌套回调

nodejs早期,开发人员使用嵌套回调处理MongoDB数据库和异步操作。虽然这种方法有效,,但它可以很快导致回调地狱,使代码难以读取和维护。

app.get('/users', (req, res) => {User.find({}, (err, users) => {if (err) {console.log(err);return res.status(500).send('Error occurred');}UserDetails.find({ userId: users[0]._id }, (err, userDetails) => {if (err) {console.log(err);return res.status(500).send('Error occurred');}return res.status(200).json({ users, userDetails });});});
});

这个代码片段演示了嵌套的回调,用于查询用户和他们的详细信息,这些信息来自于使用MongoDB数据库。可以看到管理多个嵌套的回调会变得很麻烦。

不使用嵌套回调,我们可以利用 promiseasync/await 来提高代码可读性和优雅地管理异步操作。

使用promise和async/await

promise提供了一种更整洁的方式来处理异步操作,并使代码更具可读性。下面是同样的例子,使用的是promiseasync/wawit

app.get('/users', async (req, res) => {try {const users = await User.find({});const userDetails = await UserDetails.find({ userId: users[0]._id });return res.status(200).json({ users, userDetails });} catch (err) {console.log(err);return res.status(500).send('Error occurred');}
});

使用async/await消除嵌套结构,大大提高了代码可读性。它提高了代码的可维护性,使错误处理更加简单。

缺乏错误处理

不能正确处理错误会导致意外的崩溃和潜在的安全漏洞。许多开发人员忽略了错误处理,这可能会导致他们的应用程序在使用MongoDB时表现出不可预测的行为。

app.get('/user/:id', (req, res) => {User.findById(req.params.id, (err, user) => {if (err) {console.log(err);// What if an error occurs here? It will be unhandled!}return res.status(200).json(user);});
});

在上面的示例中,如果在对MongoDB数据库查询中发生错误,将不会处理错误,,能导致意外行为或崩溃。为了解决这个问题,必须实施适当的错误处理。

实现错误处理

处理错误的方法建议是使用try/catch代码块:

app.get('/user/:id', async (req, res) => {try {const user = await User.findById(req.params.id);if (!user) {return res.status(404).json({ message: 'User not found' });}return res.status(200).json(user);} catch (err) {console.log(err);return res.status(500).send('Error occurred');}
});

通过使用try/catch块,我们可以捕捉在执行MongoDB查询期间发生的任何错误。此外,我们可以根据特定的错误类型定制错误响应,以向客户端提供信息反馈。

不使用中间件

中间件通过允许开发人员拦截和修改传入的请求,在使用MongoDB 时中间件发挥着至关重要的作用。忽略使用中间件会导致路由膨胀和代码重复。

app.get('/users', (req, res) => {// 一些逻辑// 缺乏中间件使模块化代码和处理通用功能变得困难// 将在不同的路线重复使用更多代码,导致维护问题。
});

使用中间件

中间件允许开发人员集中处理重复任务,提高代码模块化和可维护性。这里有一个使用中间件操作MongoDB 数据库的例子:

const authenticateUser = async (req, res, next) => {try {const user = await User.findById(req.userId);if (!user) {return res.status(401).send('Unauthorized');}req.user = user;return next();} catch (err) {console.log(err);return res.status(500).send('Error occurred');}
};app.get('/users', authenticateUser, (req, res) => {// 现在,这个路由处理程序可以假定用户是经过身份验证的。// 身份验证逻辑已抽象成中间件。// 其他路由也可以重用"认证用户"中间件。return res.status(200).json({ user: req.user });
});

通过利用中间件,我们保持我们的路径清洁,并专注于他们的具体任务。中间件提高了代码的可重用性,简化了调试,并使应用程序更易于管理。

不管理环境变量

在使用 MongoDB数据的应用程序中的敏感信息,如数据库凭证和API键时,不应该在代码栏中硬编码。

const databasePassword = 'mysecretpassword';
const apiKey = 'myapikey';
// 直接在代码中使用敏感信息是不安全的。
// 这些信息最终可能会进入版本控制系统,从而带来安全风险。

将敏感信息直接存储在代码中会使其面临潜在的安全漏洞,并使其难以在不同环境中管理配置。

确保环境变量的安全

为了安全地管理特定环境的配置和敏感数据,我们应该使用类似 dotenv库进行处理。

低效的数据库查询

MongoDB数据库查询效率低下,会导致响应时间慢,并对应用程序性能产生负面影响。通常,开发人员可能不会优化他们的查询,从而导致性能问题。

app.get('/products', (req, res) => {Product.find({}, (err, products) => {if (err) {console.log(err);return res.status(500).send('Error occurred');}return res.status(200).json(products);});
});

在本例中,查询使用MongoDB数据库检索所有产品,对于小型数据集来说,这可能是很好的。然而,随着数据集的增长,这个查询可能变得缓慢且资源密集。

优化数据库查询

为了提高MongoDB数据库查询的性能,开发人员应该专注于查询优化。一种常见的方法是使用select 只检索所需字段的方法:

app.get('/products', async (req, res) => {try {const products = await Product.find({}).select('name price');return res.status(200).json(products);} catch (err) {console.log(err);return res.status(500).send('Error occurred');}
});

只从products 收集数据时,我们减少了数据库和应用程序之间的数据传输量,从而提高了性能。

结论

在本文中,我们探讨了与MongoDB一起使用时的常见不良做法。我们还了解了它们的潜在缺点,并用代码示例探讨了优化的最佳实践,以纠正这些问题。

通过遵循这些最佳实践,可以确保能够带来更加高效、可维护和安全的处理。优先排序代码可读性,优雅地处理错误,并采用中间件更好地模块化。此外,使用dotenv 能更安全地管理敏感数据并优化数据库查询,以提高应用程序性能。

相关文章:

在nodejs常见的不良做法及其优化解决方案

在nodejs常见的不良做法及其优化解决方案 当涉及到在express和nodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。 在本文中,我们将探索开发人员经常遇到的几种常见的错误做法,并通过代码示例研究优化的最佳做法&…...

关于layui upload上传组件上传文件无反应的问题

最近使用layui upload组件时,碰到了上传文件无反应的问题,感到非常困惑。 因为使用layui upload组件不是一次两次了,之前每次都可以,这次使用同样的配方,同样的姿势,为什么就不行了呢? 照例先…...

容器网络之Flannel

​ 第一个问题位置变化,往往是通过一个称为注册中心的地方统一管理的,这个是应用自己做的。当一个应用启动的时候,将自己所在环境的 IP 地址和端口,注册到注册中心指挥部,这样其他的应用请求它的时候,到指挥…...

SVM(下):如何进行乳腺癌检测?

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序 第十五章 具体单板的按键驱动程序(查询方式)15.1 GPIO操作回顾15.2 AM335X的按键驱动程序(查询方式)15.2.1 先看原理图确定引脚及操作方法15.2.2 再看芯片手册确定寄存器及操作方法15.2.3 编程15.2.3.1 程序框架15.2.3.2 硬…...

MySQL体系结构和四层架构介绍

MySQL体系结构图如下: 四层介绍 1. 连接层: 它的主要功能是处理客户端与MySQL服务器之间的连接(比如Java应用程序通过JDBC连接MySQL)。当客户端应用程序连接到MySQL服务器时,连接层对用户进行身份验证、建立安全连接并管理会话状态。它还处理…...

【产品运营】如何做好B端产品规划

产品规划是基于当下掌握的多维度信息,为追求特定目的,而制定的产品资源投入计划。 产品规划是基于当下掌握的多维度信息(客户需求、市场趋势、竞争对手、竞争策略等),为追求特定目的(商业增长、客户满意等&…...

ruoyi-启动

1 springboot 版本 git 地址 ruoyi-vue-pro: 🔥 官方推荐 🔥 RuoYi-Vue 全新 Pro 版本,优化重构所有功能。基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 微信小程序,支持 RBAC 动态权限、数据权限…...

select完成服务器并发

服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …...

初级篇—第四章聚合函数

文章目录 聚合函数介绍聚合函数介绍COUNT函数AVG和SUM函数MIN和MAX函数 GROUP BY语法基本使用使用多个列分组WITH ROLLUP HAVING基本使用WHERE和HAVING的对比开发中的选择 SELECT的执行过程查询的结构SQL 的执行原理 练习流程函数 聚合函数介绍 聚合函数作用于一组数据&#x…...

计算机图像处理-中值滤波

非线性滤波 非线性滤波是利用原始图像跟模版之间的一种逻辑关系得到结果&#xff0c;常用的非线性滤波方法有中值滤波和高斯双边滤波&#xff0c;分别对应cv2.medianBlur(src, ksize)方法和cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])方法。 …...

Golang中的包和模块设计

Go&#xff0c;也被称为Golang&#xff0c;是一种静态类型、编译型语言&#xff0c;因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统&#xff0c;它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…...

web:[极客大挑战 2019]Upload

题目 页面显示为一个上传&#xff0c;猜测上传一句话木马文件 先查看源代码看一下有没有有用的信息&#xff0c;说明要先上传图片&#xff0c;先尝试上传含有一句话木马的图片 构造payload <?php eval($_POST[123]);?> 上传后页面显示为&#xff0c;不能包含<&…...

ICMP差错包

ICMP报文分类 Type Code 描述 查询/差错 0-Echo响应 0 Echo响应报文 查询 3-目的不可达 0 目标网络不可达报文 差错 1 目标主机不可达报文 差错 2 目标协议不可达报文 差错 3 目标端口不可达报文 差错 4 要求分段并设置DF flag标志报文 差错 5 源路由…...

算法基础课第二部分

算法基础课 第四讲 数学知识AcWing1381. 阶乘(同余&#xff0c;因式分解) 质数AcWing 866. 质数的判定---试除法AcWing 868. 质数的判定---埃氏筛AcWing867. 分解质因数---试除法AcWing 197. 阶乘---分解质因数---埃式筛 约数AcWing 869. 求约数---试除法AcWing 870. 约数个数-…...

【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法

目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序&#xff08;生成初始归并段&#xff09;​编辑 4、最佳归并树 4.1 理论基础​编辑 4.2 构造方法 ​编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…...

抽象工厂模式 创建性模式之五

在看这篇文章之前&#xff0c;请先看看“简单工厂模式”和“工厂方法模式”这两篇博文&#xff0c;会更有助于理解。我们现在已经知道&#xff0c;简单工厂模式就是用一个简单工厂去创建多个产品&#xff0c;工厂方法模式是每一个具体的工厂只生产一个具体的产品&#xff0c;然…...

servlet如何获取PUT和DELETE请求的参数

1. servlet为何不能获取PUT和DELETE请求的参数 Servlet的规范是POST的数据需要转给request.getParameter*()方法&#xff0c;没有规定PUT和DELETE请求也这么做 The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT or PATCH requests. T…...

【Vue.js】使用Element中的Mock.js搭建首页导航左侧菜单---【超高级教学】

一&#xff0c;Mock.js 1.1 认识Mock.js Mock.js是一个用于前端开发中生成随机数据、模拟接口响应的 JavaScript 库。模拟数据的生成器&#xff0c;用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率 总结来说&#xff0c;Element中的Mock.js是一个用于…...

从技术创新到应用实践,百度智能云发起大模型平台应用开发挑战赛!

大模型已经成为未来技术发展方向的重大变革&#xff0c;热度之下更需去虚向实&#xff0c;让技术走进产业场景。在这样的背景下&#xff0c;百度智能云于近期发起了“百度智能云千帆大模型平台应用开发挑战赛”。 挖掘大模型落地应用 千帆大模型平台应用开发挑战赛启动 在不久前…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...