这是我尝试过的第一个代码版本。我已经尝试了很多其他的东西,比如互斥,在任何地方添加catch块,以及Promise反模式,但我似乎无法克服这种心理或语法障碍:
cost_calc.style.format(formatdict)
这是populateJoins() {
let promises = [];
for (let c in this.columns) {
let transformColumn = this.columns[c];
if (transformColumn.joins) {
let joinPointer = this.databaseObject;
for (let j in transformColumn.joins) {
let join = transformColumn.joins[j];
if (joinPointer[join.as] != null) {
joinPointer = joinPointer.dataValues[join.as];
} else {
if (this.requestQuery[toCamelCase(join.as) + 'Id']) {
promises.push(
join.model.findOne({where: {id: this.requestQuery[toCamelCase(join.as) + 'Id']}})
.then((tmp) => {
joinPointer.dataValues[join.as] = tmp;
}));
} else if (joinPointer[toSnakeCase(join.as) + '_id']) {
promises.push(
join.model.findOne({where: {id: joinPointer[toSnakeCase(join.as) + '_id']}})
.then((tmp) => {
joinPointer.dataValues[join.as] = tmp;
}));
}
}
}
}
}
return Promises.all(promises);
}
:
this.columns
因此,对于我已经学过的东西, child1Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child1'),
as: 'Child1'
}],
hidden: true
},
child2Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child2'),
as: 'Child2'
}],
hidden: true
},
child1Status1Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child1'),
as: 'Child1'
},{
model: Database.getInstance().getModel('status1'),
as: 'Status1'
}],
hidden: true
},
child1Status2Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child1'),
as: 'Child1'
},{
model: Database.getInstance().getModel('status2'),
as: 'Grandchild2'
}],
hidden: true
},
serverName: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child1'),
as: 'Child2'
},{
model: Database.getInstance().getModel('grandchild'),
as: 'Grandchild'
},{
model: Database.getInstance().getModel('great_grandchild'),
as: 'GreatGrandchild'
}],
hidden: true
},
child2Status1Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child2'),
as: 'Child2'
},{
model: Database.getInstance().getModel('status1'),
as: 'Grandchild1'
}],
hidden: true
},
child2Status2Name: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child2'),
as: 'Child2'
},{
model: Database.getInstance().getModel('status2'),
as: 'Grandchild2'
}],
hidden: true
},
archetypeName: {
name: 'name',
forceSelect: true,
joins: [{
model: Database.getInstance().getModel('child2'),
as: 'Child2'
},{
model: Database.getInstance().getModel('archetype'),
as: 'Archetype'
},{
model: Database.getInstance().getModel('archetype'),
as: 'ArchetypeLink'
}],
hidden: true
},
将永远不会阻止重复的joinPointer[join.as] != null
数据库调用被触发,因为在promises完成解析之前不会填充该属性。
同样地,没有孙子会填充,因为他们必须等待孩子们居住,如果孙子们先实现,那么他们将永远不会进入子对象。对曾孙子来说同样如此。
我读了this answer,他说,“如果你已经将它们放在一个数组中,那么它们就已经在执行了。”我知道Promise的内容已经解决,这就是为什么在其他代码中我总是使用数字索引来填充对象,即Child
,但我不知道如何在这里做到这一点。
我一直在研究这个问题并且没有提出解决方案,所以任何可行的代码都不仅仅是值得赞赏的。
答案 0 :(得分:1)
问题中的代码难以理解,但看起来您尝试做的事情相当简单,即执行一系列异步findOne
查询串联并逐步构建一个更深层次的层次结构,包括返回的结果。
如果是,那么:
reduce()
模式,请参阅“The Collection Kerfuffle”here。.columns
对象是不必要的 - 您只需要.columns.greatGrandchildName.joins
。代码应至少看起来像这样:
populateJoin(joins) {
return joins.reduce((p, join) => {
return p.then(obj => {
let id = this.requestQuery[toCamelCase(join.as) + 'Id'] || obj[toSnakeCase(join.as) + '_id'] || obj[toSnakeCase(join.as + 's') + '_id'] || null;
if(id) {
return join.model.findOne({'where': { 'id': id }}).then(tmp => {
if (obj.dataValues[join.as]) {
return obj.dataValues[join.as];
} else {
obj.dataValues[join.as] = tmp;
return tmp; // 'tmp' will be `obj` at next iteration of the reduction.
}
return tmp; // 'tmp' will be `obj` at next iteration of the reduction.
});
} else {
return obj; // send unmodified obj to next iteration of the reduction.
}
});
}, Promise.resolve(this.databaseObject)) // starter promise for the reduction
.then(() => this.databaseObject); // useful though not essential to make the top level object available to the caller's .then() callback.
}
populateJoins() {
var promises = [];
for (let c in this.columns) {
let transformColumn = this.columns[c];
if (transformColumn.joins) {
promises.push(this.populateJoin(transformColumn.joins));
}
}
return Promise.all(promises);
}