0

我想使用 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);
    });
}

这看起来真的很乱,但它有效并通过了测试。您如何看待这个解决方案?

4

2 回答 2

1

它对于大型复杂对象图是不可忽略的,因为它是递归的。由于它是递归的,您可以轻松地在 setTimeout 或 setImmediate 中调用下一个递归来释放事件循环。

回复:从性能的角度来看,编辑这看起来不错。看起来它可以被重构为更具可读性,但我认为你对问题域和你精心设计的解决方案有一个坚实的掌握。

于 2013-08-14T17:11:51.167 回答
0

除非模式有数千个属性,否则它应该不是问题。尝试测量 subrutine 在“标准环境”中在最坏情况下所花费的时间如果该时间不可接受,您可以将此循环拆分为多个部分。请参阅防止长时间运行的 javascript 锁定浏览器

于 2013-08-14T17:45:37.227 回答