使用for..in阻止事件循环

时间:2013-08-14 17:05:14

标签: javascript node.js for-in-loop

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

这看起来非常混乱,但它可以工作并通过测试。您对此解决方案有何看法?

2 个答案:

答案 0 :(得分:1)

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

Re:从性能角度来看,编辑看起来不错。看起来它可以被重构为更具可读性,但我认为你已经牢牢掌握了问题领域和你所制定的解决方案。

答案 1 :(得分:0)

除非架构有数千个属性,否则它应该不是问题。尝试在“标准环境”中测量最坏情况下的小体切割时间。如果该时间不可接受,则可以将此循环分成多个部分。见Prevent long running javascript from locking up browser