试图了解node.js编程模型是如何工作的

我最近一直在阅读关于node.js(像许多其他)。 我觉得对于一些用例很有意思,但是我们有点努力去理解内部工作,特别是closures函数和代码的stream程之间的交互。

假设我有一个接受键值数组的函数。 在将数据存储到某个地方之前,函数必须检查这些值是否遵循某些数据质量准则(例如,某些键必须具有值,其他键必须具有数值等)(为了这个问题的目的,我们假设数据validation必须在应用程序中完成)。

在“常规”开发模式中,我会写这样的东西:

resultName = validateName(data.name) resultAddress = validateAddress(data.address) resultID = validateID(data.id) if (resultName && resultAddress && resultID) { store(data) else { sendErrorToUser(data) } 

获取validation结果,并向用户解释错误或存储数据并返回某种确认。 stream程非常清晰。

我理解node.js的方法是,将validation委托给不同的函数(以避免等待每个validation完成),并为validation数据块的函数提供两个callback函数:*validation成功时调用callback*validation失败时调用callback

现在很容易用“请稍等”的信息返回给用户,但是在存储数据或者向用户解释问题之前,我必须等待所有的validation清除(或者失败)。 作为一个简单的方法来弄清楚,如果所有的validation完成,我想使用一个variables,计数调用callback函数的数量,并发出一个“validation完成”事件来存储validation的数据(或返回给用户与任何错误)。 或者,也可以在每次validation完成后发出一个事件,并在发出“存储”/“错误”事件之前检查所有validation是否完成。

我的问题是 – 我正确地处理这个问题吗? 还是有更合适的方法来做这些事情与node.js(或类似的基于事件的系统)。

谢谢! 阿龙

你的validation是asynchronous的吗? 如果他们不是,你可以使用你发布的代码,“正规”之一。

如果validation是asynchronous的(例如检查电子邮件的唯一性),则需要提供callback:

 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); } }); } 

上面的代码可以通过使用已经存在的validation器或ORM模块进行简化

例如 : 蒙古validation模块 。

我们走吧。 基本上,你想要做的是沿着以下几点:

 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"); 

}

这可以通过以下方式完成(请注意我们如何将失败的键作为callback的第一个(错误)parameter passing):

 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); } }); 

纠正我,如果我错了,但我想你问的是如何处理来自多个asynchronous调用的响应。

以下是我如何做的(使用您的validation示例):

 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对象,它从空开始。 当每个字段被validation,它被添加到result对象(通过validationfunction,我已经在上面的代码片段)。 我使用了一个单一的callback方法,但是可以有多个,比如说callbackNamecallbackAddress等等。只有当result对象已经被完全填充,并且在isAllDataAvailable中被选中时,validation结果才会被处理。

希望这可以帮助。

考虑使用: https : //github.com/asaf/nodejs-model这将使你的生活更容易处理validation。