我最近一直在阅读有关node.js的内容(和许多其他人一样)。我觉得有些用例很有趣,但我有点难以理解内部工作,特别是闭包函数和代码处理流程之间的交互。
假设我有一个接受键值数组的函数。在将数据存储到某处之前,该函数必须检查值是否遵循某些数据质量指南(例如某些键必须具有值,其他键必须具有数字作为值等)(出于此问题的目的,我们假设数据验证必须在应用程序本身完成。)
在“常规”开发模型中,我会写这样的东西:
resultName = validateName(data.name)
resultAddress = validateAddress(data.address)
resultID = validateID(data.id)
if (resultName && resultAddress && resultID) {
store(data)
else {
sendErrorToUser(data)
}
获取验证结果,并向用户解释错误或存储数据并返回某种确认。流程很清楚。
我理解node.js的方式,这样做的方法是将验证委托给不同的函数(以避免等待每个验证完成),并为验证块的函数提供两个回调函数。数据: *验证成功时调用的回调 *验证失败时调用的回调
现在很容易通过“请稍候”消息返回给用户,但是在存储数据或向用户解释问题之前,我必须等待所有验证清除(或失败)。作为判断所有验证是否完成的简单方法,我想到使用一个变量来计算调用回调的函数数量,并发出“验证完成”事件来存储验证数据(或者回到用户有任何错误)。或者,或者,在每次验证完成后发出一个事件,并在该事件的代码中检查所有验证是否完成,然后发出“存储”/“错误”事件。
我的问题是 - 我正确接近这个吗?或者有更合适的方法来使用node.js(或类似的基于事件的系统)来完成这些事情。
谢谢! 阿龙
答案 0 :(得分:2)
您的验证是否异步?如果不是,您可以使用您发布的代码,即“常规”代码。
如果验证是异步的(例如检查电子邮件的唯一性),则需要提供回调:
var validateUniqueEmail = function (data, callback) {
db.find({email: data.email}, function (err, result) {
callback(err, result === null);
})
};
var validateAndStore = function (data, callback) {
asyncValidation(data, function (err, is_valid) {
if (err) {
callback(err, null);
} else if (!is_valid) {
callback('Email is not unique', null);
} else {
db.store(data, callback);
}
});
}
通过使用一些已经存在的验证器或ORM模块,可以大大简化上面的代码
答案 1 :(得分:1)
我们走吧。基本上,你想要做的是:
var validate(data, cb){
var allOk = true;
for(var key in data){
allOk = allOk && validate[key](data.key); // validator depends on the key
}
if (allOk) cb(null, data); else cb(new Error "bleh");
}
这可以通过以下方式完成(请注意我们如何将失败的密钥作为第一个(错误)参数传递给回调):
var validate(data, cb){
var status = {true:[], false:[]},
total = Object.keys(data).length,
done = 0;
for (var key in data)
(function(key){
validate[key](data[key], function(ok){
status[ok].push(key);
if (++done == total){
status[false].length ? cb(status[false]) : cb(null);
}
});
})(key);
}
您可以这样使用:
validate(data, function(failures){
if (failures){
// tell the user the input does not validate on the keys stored in failures
} else {
// all ok
store(data);
}
});
答案 2 :(得分:0)
如果我错了,请纠正我,但我认为你问的是如何处理来自多个异步调用的响应。
我是这样做的(使用验证示例):
var result = {};
function isAllDataAvailable() {
return result.name !== undefined
&& result.address !== undefined
&& result.id !== undefined;
}
function callback(error) {
if (error) {
showError(error);
// terminate here (?)
return;
}
if (isAllDataAvailable()) {
showOutput();
}
}
validateName(data, callback);
validateAddress(data, callback);
validateEmail(data, callback);
这里的关键是result
对象,它从空开始。当每个字段得到验证时,它会被添加到result
对象(通过验证函数,我在上面的代码片段中省略了它)。我使用了一个callback
方法,但您可以有多个,例如callbackName
,callbackAddress
等。仅当result
对象处理时才会处理验证结果已完全填充,已在isAllDataAvailable
中进行了检查。
希望这有帮助。
答案 3 :(得分:0)
考虑使用:https://github.com/asaf/nodejs-model 在处理验证器时,它将使您的生活更轻松。