我有一个“字符”模型,有两列保存 JSON 对象,其中存储“肢体”模型对象的数组(作为 JSON 对象)。在页面上,用户选择哪些“肢体”属于两列(“装备”或“备用”),并且该选择通过表单发送到服务器。
我知道该表单有效,因为下一页成功显示了 JSON 数组中存在的所有六个“肢体”对象。完全相同的列表应该保存到“Angular 色”的“备用”和“装备”列中。
90% 的情况下它都能完美运行。但偶尔,即使完全相同的列表成功显示了所有六个“肢体”,但实际上只有四个或五个“肢体”对象存储在“字符”数据库中。/p>
这个过程是,表单将发送一个 ID 号数组,然后服务器将根据这些 ID 从数据库中实例化“肢体”对象。正如我所说,这部分在 100% 的情况下都能完美运行,因为页面始终显示所有六个“肢体”对象。但有时完全相同的列表在存储在数据库的“字符”列中时会丢失一两个条目。 相关代码如下: 因此您可以看到完全相同的列表存储在数据库中,该列表也被发送到“viewcharacter”页面,但“viewcharacter”始终显示所有已发送和创建的“肢体”,但不显示当我更新“Angular 色”对象时,所有创建的“肢体”都存储在数据库中。 提前致谢 updateCharacter: function(req, res) {
if(req.session.user){
// FIRST get the form info and store it:
var equipped_limb_ids = req.param('char_equipped_limbs').split(",");
var spare_limb_ids = req.param('char_spare_limbs').split(",");
var new_name = req.param('new_char_name');
var char_id = req.param('char_id_out');
// Next get fresh limbs based on the limbs IDs:
var spare_limbs = { "limbs": [] };
var equipped_limbs = { "limbs": [] };
for(var i=0; i<spare_limb_ids.length; i++){
var limb_id = spare_limb_ids[i].replace(/\W/g, '');
Limb.findOne().where({ 'id': limb_id })
.exec(function(err, result){
if(result){
spare_limbs["limbs"].push(result);
}
});
}
for(var i=0; i<equipped_limb_ids.length; i++){
var limb_id = equipped_limb_ids[i].replace(/\W/g, '');
Limb.findOne().where({ 'id': limb_id })
.exec(function(err, result){
if(result){
equipped_limbs["limbs"].push(result);
}
});
}
// Prepare info to update the character, and send the same info to the front page
var updated_info = {
name: new_name,
equipped_limbs: equipped_limbs,
spare_limbs: spare_limbs
};
Character.update( { id:char_id }, updated_info )
.exec( function(err, char) {
return res.view('viewcharacter', {
name:new_name,
spares: spare_limbs,
equipped: equipped_limbs,
char_id: char_id
});
});
}else{
return res.view('login');
}
}
最佳答案
您的代码没有按照您认为的顺序运行...您放入 .exec
block 中的所有回调(包括所有数组推送)都将在稍后的某个时间点 - 无法保证按什么顺序或晚多少时间。
当代码通常有效时,这是因为通常在更新数据库中的Character
之前碰巧找到了所有肢体对象,但不能保证您编写的顺序。
要了解发生了什么,只需插入一些 sails.log
调用,例如在每个 Limb.findOne
之前,以及在每次推送到肢体数组之前。然后也是在 Character.update
和 return res.view
之前。
解决方案并不完全简单 - 您需要等待不确定数量的异步调用完成。如果您使用 Q 或 Bluebird 这样的库,他们有办法做到这一点。在不添加任何库的情况下,您可以通过组合对“肢体”的查询并巧妙地处理结果来完成这项工作:
Limb.find({id: equipped_limb_ids.concat(spare_limb_ids)}).exec(function(err, limbs) {
// handle the error...
// limbs is a list of all needed limbs in no particular order.
// create a dictionary to look up by id
var limbDict = {};
for (var i = 0; i < limbs.length; i++) { limbDict[limbs[i].id] = limbs[i]; }
// now create your limb object arrays
var equippedLimbs = [], spareLimbs = [];
// if you're comfortable with .map, you can use this, but here's the old fasioned way
for (var i = 0; i < equipped_limb_ids.length; i++) {
if (limbDict[equipped_limb_ids[i]]) {
equippedLimbs.push(limbDict[equipped_limb_ids[i]]);
}
}
for (var i = 0; i < spare_limb_ids.length; i++) {
if (limbDict[spare_limb_ids[i]]) {
spareLimbs.push(limbDict[spare_limb_ids[i]]);
}
}
// now you have all your "limbs"... update your character and return...
});
关于javascript - Sails : JSON array of Model objects successfully created and displayed, 但只有一些保存到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48477791/