我想使用revalidator(https://github.com/flatiron/revalidator)的模式定义检查Javascript对象是否有不需要的属性。
我提出了以下代码段:
function strip(object, schema) {
var strippedObject = {};
for (var property in schema.properties) {
if (schema.properties[property].type === 'object') {
strippedObject[property] = strip(object[property], schema.properties[property]);
} else {
strippedObject[property] = object[property];
}
}
return strippedObject;
}
此代码通过递归到嵌套模式的模式同步复制所需属性和循环。
我担心此时会阻止事件循环。
这可以忽略不计,因为我没有做I / O吗?
修改
感谢您的评论。就像jbaylina所提到的那样,确实存在这样的情况:模式最多嵌套2个级别,每个级别可能大约有10个属性。不过我尝试使用setImmediate它可以工作,但我可能会异步迭代它真的是一个问题:
function strip(object, schema, callback) {
var strippedObject = {};
async.each(Object.keys(schema.properties), function (property, next) {
if (schema.properties.hasOwnProperty(property)) {
if (schema.properties[property].type && schema.properties[property].type === 'object') {
strip(object[property], schema.properties[property], function (err, obj) {
if (err) return next(err);
strippedObject[property] = obj;
next();
});
} else {
strippedObject[property] = object[property];
next();
}
}
}, function (err) {
if (err) return callback(err);
return callback(null, strippedObject);
});
}
这看起来非常混乱,但它可以工作并通过测试。您对此解决方案有何看法?
答案 0 :(得分:1)
对于大型复杂对象图,这是不可忽略的,因为它是递归的。由于它是递归的,你可以轻松地在setTimeout或setImmediate中包装调用下一个递归来释放事件循环。
Re:从性能角度来看,编辑看起来不错。看起来它可以被重构为更具可读性,但我认为你已经牢牢掌握了问题领域和你所制定的解决方案。
答案 1 :(得分:0)
除非架构有数千个属性,否则它应该不是问题。尝试在“标准环境”中测量最坏情况下的小体切割时间。如果该时间不可接受,则可以将此循环分成多个部分。见Prevent long running javascript from locking up browser