Я пытаюсь найти лучший подход к использованию хуков для добавления некоторых полей к объекту, когда он сохраняется или изменяется.
Основная идея состоит в том, что есть entry
объекты, которые должны содержать набор свойств, основанных на некоторых сложных запросах и вычислениях других записей. Все эти вычисленные свойства хранятся в свойстве с именем derived
. Было бы слишком дорого вычислять entry.derived
каждый раз, когда это необходимо, или когда он считывается из БД. Вместо этого я решил заранее заполнить свойство derived
, и крючки кажутся лучшим местом для этого.
Кажется, это не проблема для хука creating
. Однако мне также нужно повторно сгенерировать derived
, если какое-либо другое свойство в entry
изменится. Хук updating
требует, чтобы я отправлял дополнительные изменения, возвращая их, что проблематично, потому что единственный способ сгенерировать изменение - это асинхронный вызов.
Ниже приведен минимальный код, который пытается продемонстрировать проблему. Я еще не пробовал вариант B
, но подозреваю, что он тоже не сработает.
const entryDerivedData = function(entry) {
// query a bunch of data from entries table then do some calculations
return db.entries.where('exerciseID').equals(entry.exerciseID).toArray()
.then(e => {
// do some calculation and return
return calculateDerivedData(e);
});
};
// A: Can't do this because `hook` isn't expecting a generator func
db.entries.hook('updating', function*(mods, primKey, entry, transaction) {
const derived = yield entryDerivedData(entry);
return derived;
});
// B: Another possibility, but probably won't work either
db.entries.hook('updating', function(mods, primKey, entry, transaction) {
transaction.scopeFunc = function() {
return entryDerivedData(entry)
.then(derived => {
// Won't this result in another invocation of the updating hook?
return db.entries.update(entry.id, {derived});
});
};
});