我需要迭代Bookshelf集合中的所有模型,计算一些信息,然后将这些信息存储回每个模型中。在单个事务中执行此操作非常重要,以便对错误进行回滚。
我遇到的问题是我真正想到的唯一方法是使用Promise.map
(蓝鸟),但书架集合无法传递到地图。例如,这不起作用(Thing
是模型,Promise
是蓝鸟承诺):
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return Promise.map(things, function (thing) {
return thing.save({
value: computeSomeValueSync(thing)
}, {
transacting: t
});
});
});
}).tap(function () {
console.log("update complete");
});
因为things
无法传递给Promise.map
,并且Bookshelf API中似乎没有任何内容可以从集合中获取模型数组。
我该怎么做?
答案 0 :(得分:0)
好吧,我至少找到了 解决方案。
第一步是编写一个计算和保存值的函数,并使其成为书架模型的成员。因此,对于我的帖子中的示例,我在扩展模型时在Thing
中定义了以下函数:
... = bookshelf.Model.extend({
...
updateSomeValue: function (options) {
return this.save({
value: computeSomeValueSync(this)
}, options);
}
});
其中options
是传递给保存的选项,我们可以使用它来传递事务。很容易。 然后,我们可以使用Collection#invokeThen
执行等效的Promise.map
,如下所示:
Bookshelf.transaction(function (t) {
return Thing.fetchAll({transacting:t}).then(function (things) {
return things.invokeThen("updateSomeValue", {transacting:t});
});
}).tap(function () {
console.log("update complete");
});
在那里,invokeThen
基本上完成了我打算用Promise.map
做的事情 - 返回一个承诺,一旦履行了Thing#updateSomeValue
返回的所有承诺,就会履行承诺。
由于我必须添加模型方法,这只是稍微不方便,但 至少有点意义。界面有点奇怪,因为文档很难拼凑在一起。但是,至少它是可能的。
仍然对其他想法持开放态度。