如何在不触发模型生命周期回调的情况下更新SailsJS中的记录

时间:2014-10-17 14:35:05

标签: javascript sails.js waterline

我有模型,我需要在更新或保存新记录到表后重建记录。问题是在fixTree上进行了更新后触发了afterUpdate回调。

module.exports = {
  identity: 'Role',
  attributes: {
    ..
  },
  afterCreate: function(rec, cb) {
    fixTree();
    cb();
  },
  afterUpdate: function(rec, cb) {
    fixTree();
    cb();
  },
}

function fixTree() {
  /* code here */
  Role.update(....); // <--- do not trigger afterUpdate
  /* and code here */
}

2 个答案:

答案 0 :(得分:2)

如果正在进行树更新,您可以添加一个标志来监控:

var fixTreeInProgress = false;

module.exports = {
  identity: 'Role',
  attributes: {
  //..
  },
  afterCreate: function(rec, cb) {
    if (!fixTreeInProgress) {
      fixTree();
    }
    cb();
  },
  afterUpdate: function(rec, cb) {
    if (!fixTreeInProgress) {
      fixTree();
    }
    cb();
  },
}

function fixTree() {
  /* code here */
  fixTreeInProgress = true;
  //passing callback to clear out flag when update is complete
  Role.update(criteria, updatedRecords, function fixTreeUpdateCallback() {
    fixTreeInProgress = false;
  }); // <--- do not trigger afterUpdate

  /* and code here */
}

但请记住:如果在Role.update正在进行时数据将在另一个请求中更新,则会使您的数据不一致:

考虑这种情况:

  1. 应用程序接收数据更新请求。
  2. 控制器更新数据,生命周期回调称为
  3. fixTreeInProgress var是false,因此我们启动fixTree(),并将fixTreeInProgress设置为true
  4. 应用程序再接收一个数据更新请求。
  5. 控制器更新数据,生命周期回调被调用,fixTreeInProgress var为true,因此我们启动fixTree()
  6. Role.update()已完成,fixTreeInProgress已设置为false
  7. 在这种情况下,我们将使用旧版本的数据更新树。

    您需要使用某种任务队列(以及可选的某种去抖功能)来处理这种情况。

答案 1 :(得分:2)

我最终使用控制器操作

create: function(req, res) {
    var data = {};
    data.name = req.body.name;
    data.parent = req.body.parent;
    Role.create(data, function(err, record) {
        Role.tree.fix(function() {
            res.ok(record);
        });
    });
},
update: function(req, res) {
    var data = {};
    data.name = req.body.name;
    data.parent = req.body.parent;
    Role.update(req.params.id, data, function(err, record) {
        Role.tree.fix(function() {
            res.ok(record);
        });
    });
},