当前位置: 首页 > 知识库问答 >
问题:

在Node.js中将业务逻辑从控制器重构为服务

长孙阳州
2023-03-14

我正在学习Node.js,但我在代码重构方面遇到了问题。我阅读了Node.js中的代码体系结构和良好的编码实践,我想重构我的代码。

我的当前代码:

User.Controller.js

const bcrypt = require('bcryptjs');
const User = require('../models/user');

exports.createUser = (req, res, next) => {
  bcrypt.hash(req.body.password, 10)
    .then(hash => {
      const user = new User({
        email: req.body.email,
        password: hash
      });
      user.save()
        .then(result => {
          res.status(201).json({
            message: 'User created!',
            result: result
          })
        })
        .catch(err => {
          res.status(400).json({
            message: 'An unknown error has occurred.'
          })
        });
    });
}

我想把所有的业务逻辑放到服务中。我试过这样的方法:

User.Controller.js

const UserService = require('../services/user.service');

exports.createUser = async function (req, res, next) {

  try {
    var result = await UserService.createUser(req.body.email, req.body.password);
    return res.status(200).json({ result: result, message: "User created!" });
  } catch (e) {
    return res.status(400).json({ message: e.message });
  }

}

user.service.js

const bcrypt = require('bcryptjs');
const User = require('../models/user.model');

exports.createUser = async function (email, password) {

  bcrypt.hash(password, 10)
    .then(hash => {
      const user = new User({
        email: email,
        password: hash
      });
      user.save()
        .then(result => {
          return result;
        })
        .catch(err => {
          throw new Error(err);
        });
    });

}

但关于诺言,我有很多错误:

(node:3760) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not ha
ndled with .catch(). (rejection id: 1)
(node:3760) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我是node.js和JavaScript的新手。怎么解决这个问题?

共有2个答案

缑桐
2023-03-14

谢谢你的回答。我修改了我的代码,现在看起来是这样的:

User.Controller.js

const UserService = require('../services/user.service');

exports.createUser = async function (req, res, next) {

  try {
    let user = await UserService.createUser(req.body.email, req.body.password);
    return res.status(201).json({ data: user, message: 'User created!' });
  } catch (e) {
    let errorMsg;
    let statusCode;
    if(e.errors['email'].kind === 'unique') {
      statusCode = 422;
      errorMsg = 'E-mail already exists.';
    } else {
      statusCode = 500;
      errorMsg = 'An unknown error has occurred.';
    }
    return res.status(statusCode).json({ message: errorMsg });
  }

}

user.service.js

const bcrypt = require('bcryptjs');
const User = require('../models/user.model');

exports.createUser = async function (email, password) {
  const hash = bcrypt.hashSync(password, 10);
  const user = new User({
    email: email,
    password: hash
  });
  await user.save();
  return result;
}

我的代码正确吗?我说的是编码架构。工作很好,但我不确定我的代码是否是“良好的实践”编程。我这样问是因为我想开始写整个后端,而我不确定我的代码。

null

  } catch (e) {
    let errorMsg;
    let statusCode;
    if(e.errors['email'].kind === 'unique') {
      statusCode = 422;
      errorMsg = 'E-mail already exists.';
    } else {
      statusCode = 500;
      errorMsg = 'An unknown error has occurred.';
    }
    return res.status(statusCode).json({ message: errorMsg });
  }

例如,在其他控制器中,我将有5个If语句。这是正确的解决方案吗?我在这里征求意见,什么可以改变,使代码专业化。

颜宸
2023-03-14

如果你想要tu使用承诺就使用承诺,当编码一致性是黄金的时候。如果您想使用async await(承诺的语法糖),那么在任何地方都要坚持使用async await。

承诺在结尾处使用链式捕获处理错误。

MyPromise().then(() => bar).catch((err) =>  do something with err )

对于async/await,应该将

try { } catch (err) {}

在您的例子中,它只是说在任何包含承诺的异步函数中,您应该用try catch包装它们。

希望有帮助。我最后的建议是,先学一种方法,然后再学另一种方法,不要把它们混在一起。

 类似资料:
  • 问题内容: 我对node.js相当陌生,并且发现随着项目规模的扩大,将一个项目分成多个文件非常复杂。我之前有一个大文件,可以同时用作多人HTML5游戏的文件服务器和Socket.IO服务器。理想情况下,我想将文件服务器,socket.IO逻辑(从网络读取信息并将其写入带有时间戳的缓冲区,然后将其发送给所有其他播放器)和游戏逻辑分开。 使用socket.io中的第一个示例来演示我的问题,通常有两个文

  • 问题内容: 软件体系结构中的域对象和域服务是什么?我不熟悉它们,或者它们与业务逻辑层有何不同? 问题答案: 不同的人以不同的方式使用这些术语,但这是我的看法: 1)“业务”和“域”大致是同义词。“域”更为通用,因为它不会假设您正在编写业务应用程序。因此,如果我们正在编写科学应用程序或游戏,则可能更喜欢将代码的相关部分称为“域”代码,而不是“业务”代码。因此,在本说明的其余部分中,我将使用“域”,因

  • 本文向大家介绍Jmeter逻辑控制器事务控制器使用方法解析,包括了Jmeter逻辑控制器事务控制器使用方法解析的使用技巧和注意事项,需要的朋友参考一下 一、基本概念: Transaction controller:一般是指要做的或所做的事情,在关系数据库一个事务可以是一条SQL语句,一组SQL语句或整个程序、在实际的工作过程中,将完成一个业务的一系列操作称作为事务,我们来举最为典型的用户登录场景为

  • 综述 在多功能的动态web应用程序中测试业务逻辑漏洞需要用非常规手段来思考。如果应用认证机制原先以1、2、3的步骤依次执行的验证身份目的来开发,万一用户从步骤1直接跳到步骤3会发生什么?用更加简单的例子来说,在打开失败、权限拒绝或仅仅500的错误的情况下,应用程序是否依然能够提供访问权限? 可以举出许多例子,但是不变的思想是“跳出常规思维”。这种类型的漏洞无法被漏洞扫描工具探测到,依赖于渗透测试人

  • 1.1  概述 业务逻辑模块主要用于编写业务逻辑,一般包含三个子模块:action(定义action和procedure)、code(业务逻辑的实现,一般使用java实现,有src,dsrc,lib)、fn(函数定义)。 1.2  Action定义 语法: <action name=" n" global="true" log-enabled="true" procedure=" "> <参

  • 因此,每个功能区显然都在数据库中,但它们还需要一些逻辑来确定用户何时获得了功能区。 按照我的编码方式,是一个简单的接口: 是一个抽象类,它实现了接口,避免了方法的定义: 现在,将像这样实现一个特定的功能区: 这段代码工作得很好,表是按照我期望的方式在数据库中创建的(我在本地环境中使用DDL生成)。 问题是,在域对象中编写业务逻辑感觉是错误的。这是好的练习吗?你能提出一个更好的解决方案吗?此外,我不