猫鼬。等待数据的后处理

Mongoose. Postprocessing of awaiting data

我是前端开发人员,我第一次使用基于 Express + MongoDB 的 RBAC API。我需要对通过 await 函数获得的 Role 权限进行后处理。示例(此代码效果很好):

export async function getRoleById(req, res) {
  try {
    const role = await Role.findById(req.params.id)
      .populate('permissions');
    return res.status(HTTPStatus.OK).json(role);
  } catch (err) {
    return res.status(HTTPStatus.BAD_REQUEST).json(err);
  }
}

结果:

{
    "id": "5c27d6bfc51081331411dcd8",
    "name": "writer2",
    "permissions": [
        {
            "id": "5c27c43e2eb0c279ccd945ef",
            "action": "create",
            "subject": "task"
        },
        {
            "id": "5c27c4532eb0c279ccd945f1",
            "action": "read",
            "subject": "task"
        }
    ]
}

但我需要另一种格式的权限:

{
    "id": "5c27d6bfc51081331411dcd8",
    "name": "writer2",
    "permissions": [
        [ "create", "article" ],
        [ "list", "user" ]
    ]
}

所以我尝试这样做:

export async function getRoleById(req, res) {
  try {
    const role = await Role.findById(req.params.id)
      .populate('permissions')
      .then((foundRole) => {
        foundRole.permissions = foundRole.permissions.map(item => [ item.action, item.subject]);
        return foundRole;
      });
    return res.status(HTTPStatus.OK).json(role);
  } catch (err) {
    return res.status(HTTPStatus.BAD_REQUEST).json(err);
  }
}

将 then 替换为 exec 并没有改变这种情况。执行此代码后,我得到响应 200,但没有任何数据。空白页面而不是带有角色数据的对象。

我阅读了很多关于 Mongoose 查询的文章,以及为什么将 async/await 与回调一起使用是不正确的。在我的情况下,用 Promises 替换 async/await 是不可接受的方式。但是我应该怎么做才能得到我需要的结果呢?

数据后处理通过 Schema 的标准方法 .toJSON() 进行。所以我们可以创建自己的方法,例如 .toMyJSON() 或重新定义标准方法。我选择第二种方式

在文件 role.model.js 中,我放置角色架构的位置:

import mongoose, { Schema } from 'mongoose';
import uniqueValidator from 'mongoose-unique-validator';

import User from '../users/user.model';

const RoleSchema = new Schema({
  /* here goes Schema */
});

/* Redefine standard method toJSON */
RoleSchema.methods = {
  toJSON() {
    return {
      id: this._id,
      name: this.name,
      permissions: this.permissions.map(item => [item.action, item.subject]),
    };
  },
};

RoleSchema.statics = {
    /* Here goes static methods of Schema */
};

export default mongoose.model('Role', RoleSchema);

现在我们可以使用这个方法:

export async function getRoleById(req, res) {
  try {
    const role = await Role.findById(req.params.id).populate('permissions');
    return res.status(HTTPStatus.OK).json(role.toJSON()); // Here we use toJSON method.
  } catch (err) {
    return res.status(HTTPStatus.BAD_REQUEST).json(err);
  }
}