Ramda IfElse 传递另一个参数的最佳方式

Ramda IfElse best way to pass another parameter

在我使用 express 和 mongoose 的 NodeJS 项目中,我决定使用 RamdaJS 来获得一些函数式编程的经验。

我有两个像

这样的预存挂钩
UserSchema.pre('save', async function (next) {
    if (!this.isModified('username')) {
        return next();
    }

    const total = await this.constructor.countUsersWithUsername(this.username);
    if (total > 0) {
        return next(new Error(`Username ${this.username} is already taken`));
    }

    return next();
});

UserSchema.pre('save', async function (next) {
    if (!this.isModified('email')) {
        return next();
    }

    const total = await this.constructor.countDocuments({ email: this.email });
    if (total > 0) {
        return next(new Error(`Email ${this.email} is taken`));
    }

    return next();
});

If 条件似乎是使用 Ramda 的好地方,我更改了我的代码

const total = await this.constructor.countUsersWithUsername(this.username);
const isUsernameTaken = R.ifElse(
    R.gt(0),
    () => next(),
    () => next(new Error(`Username ${this.username} is already taken`))
);
return isUsernameTaken(total);

这行得通,但我开始考虑我可以将 IfElse 重构到一个不同的模块中,然后我需要传入 next 和一个标签,这样我就可以说 ${label} ${value} 已经被采用。

我将如何重构它?

Mongoose 也是基于 class 的,是否有功能库可以与 MongoDB 连接?

我不会费心用 Ramda 做这个。 Ramda 的 ifElse 偶尔很有用,但大多数时候并不值得。通常只需要一个条件表达式(三元)。请注意,我是 Ramda 的创始人和忠实粉丝;但我有很多时候现代 JS 也一样好,或者在这里,甚至更老的 JS。

这将是我的方法,而不是试图弄清楚如何在你的钩子中调用它:

const isTaken = (label) => (value, count, next) =>
  count > 0
    ? next (new Error (`${label} ${value} is already taken`))
    : next ()

const isUsernameTaken = isTaken('Username')
const isEmailTaken = isTaken('Email')

const next = (err) => {
  console.log(err ? `${err}` : `Success`)
}

isUsernameTaken('Fred', 2, next);
isUsernameTaken('Wilma', 0, next);
isEmailTaken('fred@bedrock.com', 0, next)
isEmailTaken('wilma@stoneage.com', 1, next)

无论您是想要特定的助手 isUsernameTakenisEmailTaken 还是只想调用通用的 isTaken 都将决定您是否应该柯里化第一个参数。应该很容易改变。