JavaScript NodeJs - 如何重构这一点

标签 javascript node.js mongodb express

所以我正在创建一个简单的 CRUD 应用程序,但我偶然发现最新创建的帐户的 MongoDB 自动递增值。

更具体地说,我编写了下面的花絮以启用以下功能:

1)注册时,进行一些验证检查

2) 查看最新帐号是多少,加1

3)创建新用户,添加到DB

现在,如果您看到下面的内容,我已经标记了三个展品

1 & 2)出于某种奇怪的原因,如果我从路线本身中删除代码,那么它就会停止正常工作,但我不知道如何摆脱重复的代码,因为功能几乎相同,但删除其中任何一个都会破坏顺序。我怎样才能解决这个问题并使我的代码更整洁?

3)我如何将这个函数提取到一个单独的函数中?经过一番摆弄之后,我只到达了“accountNumber 未定义”的地步。

const getLastAccountNumber = function() {
  User.find({}, { accountNumber: 1, _id: 0 }) **// EXHIBIT 1**
    .sort({ accountNumber: -1 })
    .limit(1)
    .then(function(doc) {
      if (!doc) throw new Error("Error?");
      accountNumber = doc[0].accountNumber;
      return doc[0].accountNumber;
    });
};
// TODO: Refactor methods

router.post(
  "/register",
  [check("email").isEmail(), check("password").isLength({ min: 4 })],
  function(req, res) {
    User.find({}, { accountNumber: 1, _id: 0 }) **// EXHIBIT 2**
      .sort({ accountNumber: -1 })
      .limit(1)
      .then(getLastAccountNumber())
      .then(function() { **// EXHIBIT 3**
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
          return res.status(422).json({ errors: errors.array() });
        }
        const { email, password } = req.body;
        const amount = 0;
        accountNumber++;
        const user = new User({
          email,
          password,
          accountNumber,
          amount
        });
        user.save(function(err) {
          if (err) {
            console.log(err);
            res.status(500).send("Error registering new user");
          } else {
            res.status(200).send("User successfully added");
          }
        });
      });
  }
);

非常感谢任何反馈!

最佳答案

关于您的错误,我相信通过在文件顶部添加 let accountNumber; 来定义变量可能足以让您的代码正常工作,(尽管我不认为它是一个很好的解决方案...),尽管当您询问重构时:

  • 拥抱 promise :想象一下水/数据流经一系列管道,在每一步中,数据都可以进行转换。保持这种线性流程通常会使代码干净且易于理解。如果途中发生任何错误,则绕过“catch”之前的所有管道。
  • 如果发生错误并且我们直接“捕获”,我们可能希望根据失败原因以不同的方式处理情况。因此,我们可以添加错误包装器(例如 ValidationError)来检查。
  • 此外,我们可以正确命名管道,例如 getNewAccountNumber,即使数据库中没有帐户,它也可以工作
  • 箭头函数很不错
<小时/>
// error handling

class ValidationError {
  constructor (errors) {
    this.errors = errors
  }
}

const checkValidation = (req, res)=> {
  const errors = validationResult(req)
  return errors.isEmpty()
    ? Promise.resolve()
    : Promise.reject(ValidationError(errors.array()))
}

const successResponse = (req, res, data)=> ()=> res.status(200).send(data)
const errorResponse = (req, res, message = 'Internal Server Error')=> error=>
    error instanceof ValidationError ? res.status(422).json({ errors: error.errors })
  : (console.error(error), res.status(500).send(message))


// utils

const initialAccountNumber = 0
const getNewAccountNumber = ()=> User
  .find({}, { accountNumber: true, _id: false })
  .sort({ accountNumber: -1 })
  .limit(1)
  .then(xs=> !xs || !xs.length
    ? initialAccountNumber
    : xs[0].accountNumber + 1)


// route

router.post('/register', [
  check('email').isEmail(),
  check('password').isLength({ min: 4 })
], (req, res)=> checkValidation(req, res)
  .then(getNewAccountNumber)
  .then(newAccountNumber=> {
    const { email, password } = req.body
    return new User({
      email,
      password,
      accountNumber: newAccountNumber,
      amount: 0,
    })
  })
  .then(user=> user.save())
  .then(successResponse(req, res, 'User successfully added'))
  .catch(errorResponse(req, res, 'Error registering new user'))
)

无论如何,如果可能的话,我更愿意使用现有的数据库内置解决方案将其作为一项事务来执行(例如,_id 已经“保证”是唯一的,而使用此解决方案的 accountNumber 则不那么多)。

关于JavaScript NodeJs - 如何重构这一点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57027929/

相关文章:

node.js - 使用 mongoose 在 mongodb 上执行 mapreduce 时不能在 reduce 函数中使用 underscore.js

javascript - 从 Node 批量插入 mongoDB

node.js - mongoose 模型可以更新 Object Id 字段吗?

javascript - 加载新内容的加载栏

javascript - 如何调用文本框中的文本以在 javascript 中设置变量

node.js - Raspberry Pi 3 脚本 RAM 使用情况

mongodb - 根据计算值对集合进行排序

mongodb - MongoDB 中是否可以对嵌入文档执行条件查询?

javascript - Google Maps Api 使用自定义字符串运行 getPlaces

javascript - 对其他页面的 AJAX 请求不起作用