MEAN 2 多租户(多个 collection 保存相互引用)

MEAN 2 Multi Tenancy (Multiple collection saves that reference each other)

因此,在学习 JS 尤其是 MEAN 2 堆栈的同时,我正在尝试构建一个基本的多租户应用程序。我正在构建快速注册路线,我试图实现的流程是:

使用公司名称、电子邮件和密码注册。该信息将用于保存新租户,然后 return 新租户的 _id,然后使用此新 ID、电子邮件和密码保存新用户。

最接近的是:

router.post('/', function (req, res, next) {

  var tenant = new Tenant({
    name: req.body.name
  });
  var newTenant;

  tenant.save(function (err, tenant) {
    if (err) {
      return res.status(500).json({
        title: 'An error has occured',
        error: err
      });
    }
    res.status(201).json({
      message: 'Tenant created',
      obj: tenant
    });
    return(tenant._id);
    newTenant = tenant;
  });

  Tenant.findById(newTenant._id, function(err, tenant) {
    if (err) {
      return res.status(500).json({
        title:'An error occured',
        error: err
      });
    }
    var user = new User({
      email: req.body.email,
      password: bcrypt.hashSync(req.body.password, 10),
      active: req.body.active,
      tenant: tenant
    });
    user.save(function (err, user) {
      if (err) {
        return res.status(500).json({
          title: 'An error has occured',
          error: err
        });
      }
      res.status(201).json({
        message: 'User created',
        obj: user
      });
    });
  });

});

module.exports = router;

我收到一个错误:发送后无法设置 headers。 我想我知道我哪里错了,returning 租户信息。我认为异步是答案,但无法弄清楚如何实现它。抱歉,如果这是一个愚蠢的问题,或者我遗漏了一些明显的东西,我对此非常陌生,回调正在发挥作用。

发生这种情况是因为 res.status() 一发射就设置 headers。您在检查错误时尝试多次执行此操作,然后尝试在 Tenant.findById().

中再次设置状态代码

您最终的流程如下:

if (err) set headers
set headers (again)
findById()
if (err) set headers
set headers (again)

在写下你的回应时你必须小心,你只在你的逻辑流程的最后一点做。您还可以设置全局错误处理程序和 throw new Error() 并立即停止逻辑流 处理输出。如果不这样做,即使遇到错误,您的代码也会继续执行。

另一个提示:回调不适用于 returns。尽管您可以安排它们工作,或者改为实现 promise 架构,但最简单的解决方法(也是最容易学习的)是让您的函数全部异步。

试试像这样的东西:

tenant.save(function (err, tenant, callback) {
  // add a callback param to your fn ^
  if (err) {
    throw({
      code: 500,
      title: 'An error has occured',
      error: err
    });
  } else {
  // ^ add an else statement so you don't set the headers twice 
  // (because res.status() sets headers)
    res.status(201).json({
      message: 'Tenant created',
      obj: tenant
    });
  }
  callback(err, tenant);
  // call your async function instead of return, 
  // and pass both err and tenant as params
  // (one or the other may be undefined though, if it fails/succeeds)
});

...为您的其余任务创建额外的独立函数(甚至模块),然后您可以这样调用您的函数:

tenant.save(function(err, tenant) {
  Tenant.findById(tenant._id, function(err, tenant) {
    var user = new User({...})
    user.save()
  });
});