我有一个cron作业,它擦除网站上的项目列表,然后在数据库中插入或更新记录。当我刮擦页面时,我想为尚未创建的新记录创建记录,否则更新任何现有记录。目前我正在做这样的事情:
// pretend there is a "Widget" model defined
function createOrUpdateWidget(widgetConfig) {
return Widget.find(widgetConfig.id)
.then(function(widget) {
if (widget === null) {
return Widget.create(widgetConfig);
}
else {
widget.updateAttributes(widgetConfig);
}
});
}
function createOrUpdateWidgets(widgetConfigObjects) {
var promises = [];
widgetConfigObjects.forEach(function(widgetConfig) {
promises.push(createOrUpdateWidget(widgetConfig));
});
return Sequelize.Promise.all(promises);
}
createOrUpdateWidgets([...])
.done(function() {
console.log('Done!');
});
这似乎工作正常,但我不确定我是否“正确”这样做。执行数据库交互的所有承诺是否需要以串行方式运行,或者我是如何定义它们的?有没有更好的方法来做这种事情?
答案 0 :(得分:7)
你正在做的事情非常惯用且非常好,唯一的改进空间是利用Sequelize使用Bluebird作为承诺的事实,这样你就可以免费获得.map
,这可以让你转换:
function createOrUpdateWidgets(widgetConfigObjects) {
var promises = [];
widgetConfigObjects.forEach(function(widgetConfig) {
promises.push(createOrUpdateWidget(widgetConfig));
});
return Sequelize.Promise.all(promises);
}
分为:
function createOrUpdateWidgets(widgetConfigObjects) {
return Sequelize.Promise.map(widgetConfig, createOrUpdateWidget)
}
除了那种微小的改进之外 - 你正确地链接了承诺并且似乎正确地挂了它。