试图了解node.js编程模型的工作原理

时间:2011-03-17 08:35:23

标签: node.js

我最近一直在阅读有关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(或类似的基于事件的系统)来完成这些事情。

谢谢! 阿龙

4 个答案:

答案 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模块,可以大大简化上面的代码

示例mongolia validator module

答案 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方法,但您可以有多个,例如callbackNamecallbackAddress等。仅当result对象处理时才会处理验证结果已完全填充,已在isAllDataAvailable中进行了检查。

希望这有帮助。

答案 3 :(得分:0)

考虑使用:https://github.com/asaf/nodejs-model 在处理验证器时,它将使您的生活更轻松。