对于针对GET请求的每种对象类型,我都有一个有效查询参数的对象。
var queryFields = {
'organisation': ['limit', 'page', 'id', 'search'],
'actor': ['limit', 'page', 'id', 'search'],
'version': ['limit', 'page', 'search'],
'product': ['limit', 'page', 'search', 'id', 'type', 'brand', 'model', 'manufacturerSpid'],
'asset': ['limit', 'page', 'search', 'order', 'sort', 'id', 'name', 'currentCustodianSpid', 'currentLocationSpid', 'productSpid', 'search'],
'location': ['limit', 'page', 'search', 'id'],
'workorder': ['limit', 'page', 'search', 'id', 'type', 'status', 'requirementSpid', ],
'move': ['limit', 'page', 'search'],
'transfer': ['limit', 'page', 'search'],
'requirement': ['limit', 'page', 'search', 'id', 'type', 'source', 'productSpid', 'status', ],
'artefact': ['limit', 'page', 'search'],
'attestation': ['limit', 'page', 'search'],
};
我想使用此功能来确保仅接受这些有效参数的请求。现在,promise使用有效,无效或0参数解析false
。我过滤的方式似乎有问题。我传入对象类型和请求。如果请求包含查询参数,我想从对象中获取有效参数,并检查req
中的参数是否都与对象中的参数有效匹配。如果有任何无效的,我想解决false
。如果没有参数,我要解析true
。如果只有有效的参数,我想解析true
。我可以对此功能进行一些调整以获得该结果吗?
function getQueryFields(object) {
if (utils.isDefined(queryFields[object])) return queryFields[object];
return [];
}
function fieldValidator (objType, req) {
return new Promise(function(resolve) {
if (utils.isDefined(req.query)) {
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) { return Object.keys(req.query).indexOf(field) > -1;});
if (Object.keys(req.query) !== Object.keys(fields)) {
resolve(false);
} else {
resolve (true);
}
} else {
resolve(true);
}
});
}
答案 0 :(得分:1)
您的功能存在一些问题。我想先解决第一个问题,然后再讨论您的实际问题,因为这将使清晰度大大提高。首先:您不需要Promises,这是一个同步功能。
重写#1:
function getQueryFields(object) {
if (utils.isDefined(queryFields[object])) return queryFields[object];
return [];
}
function fieldValidator (objType, req) {
if (utils.isDefined(req.query)) {
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) {
return Object.keys(req.query).indexOf(field) > -1;
});
if (Object.keys(req.query) !== Object.keys(fields)) {
return false;
} else {
return true;
}
}
} else {
return true;
}
此函数可以使用的另一件事是“提前”返回。这样可以更轻松地跟踪正在发生的事情并减少分支的数量:
重写#2:
function fieldValidator (objType, req) {
if (req.query === undefined) {
return true;
}
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) {
return Object.keys(req.query).indexOf(field) > -1;
});
return (Object.keys(req.query) === Object.keys(fields));
}
这些都不能回答您的问题,但我需要它来使您在做的事情更加清晰=)
问题实际上在于比较Object.keys()
。 Object.keys()
返回一个迭代器,但是它返回的每个迭代器都是唯一的。
Javascript中的对象无法真正按“值”进行比较。按值比较对象的唯一方法是逐个检查其键。
由于您希望属性完全匹配 ,因此我想将其更改为:
基于此,我认为这将是我的版本:
function fieldValidator(objType, req) {
if (!req.query || Object.keys(req.query).length === 0) {
// Covers the 'undefined' and 'empty object' case
return true;
}
const fields = getQueryFields(objType);
const keys = Object.keys(req.query);
// Do we have enough query parameters?
if (keys.length !== fields.length) return false;
// Does every query parameter appear in the list?
for(const key of keys) {
if (!fields.includes(key)) return false;
}
return true;
}
答案 1 :(得分:0)
“字段”是键名的数组。您正在对照键名数组的对象键检查req.query键的数组。那就是数组的索引,只是连续的整数["0", "1", "2", ... etc]
。更不用说,您正在两个数组之间进行不等式检查,除非引用相同,否则这将永远是不正确的,否则它们将不在此处。因此,当然,第一个条件始终会失败并解析为false。在控制台中尝试一下:[1, 2, 3] === [1, 2, 3]
将为假(与宽松的相等性检查相同),因为它们是恰好具有相同条目的不同对象。
因此,我认为一个更好的方法是更改过滤器,以便过滤掉列表中的每个查询字段,并确保最终数组中没有条目(因为剩下的任何内容都是与列表不匹配的键)
fields = Object.keys(req.query).filter(function(field) { return fields.indexOf(field) > -1;});
if (fields.length > 0) {
resolve(false);
} else {
resolve (true);
}
(我假设您有一个使用Promise的原因,如果没有,那么我会赞同Marcos Casagrande的建议,彻底摆脱Promise并直接从函数中返回true或false。)< / p>
答案 2 :(得分:0)
如果使用expressjs,有一种使用check api的好方法。