2014-10-17 1 views
1

У меня есть модель, где мне нужно перестроить записи после обновления или сохранения новой записи в таблицу. Проблема в том, что callback afterUpdate запускается при исправлениях, сделанных fixTree.Как обновить запись в SailsJS без вызова обратных вызовов жизненного цикла модели

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 */ 
} 
+0

Хороший вопрос. Указывает на того, кто получает этот. Я думаю, что это должен быть запрос функции, чтобы иметь возможность игнорировать обратные вызовы. – Meeker

ответ

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); 
     }); 
    }); 
}, 
1

Вы можете добавить флаг для контроля, если обновление дерева продолжается:

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 ВДП false, поэтому мы запускаем fixTree() и установите fixTreeInProgress в true
  4. App получает еще один запрос на обновление данных.
  5. контроллер обновляет данные, жизненный цикл обратного вызова вызывается, fixTreeInProgress ВДП true, поэтому мы сделать не запуск fixTree()
  6. Role.update() завершена, fixTreeInProgress набор для false

В этом случае у нас будет дерево, обновленное старой версией данных.

Чтобы справиться с такими ситуациями, вам необходимо использовать какую-то очередь задач (и, необязательно, какую-то функцию дебютации).

+0

Это обходное решение, но включает в себя слишком много хлопот ... – icebreaker

+0

Существует не очень простой способ добиться этого из-за асинхронного характера node.js – ataman

Смежные вопросы