节点js中的'条件地狱'

时间:2014-01-23 05:47:21

标签: node.js design-patterns express

我的应用程序(express)中有两个层,首先是带有处理数据库查询,fs等功能的模块。第二是处理请求(也称为控制器/路由)。我只是厌倦了所有这些条件。

示例代码:

    exports.updateImage = function(image, userId, callback) {
  fs.readFile(image.path, function (err, imageBinary) {
    if (err) callback(err);
    else {
      pg.connect(conString, function(err, client, done) {
        done();
        if (err) callback(err);
        else {
          client.query('UPDATE images SET data=$1, filesize=$2, filename=$3 WHERE user_id=$4', [imageBinary, image.size, image.originalFilename, userId], function(err) {
            if (err) callback(err);
            else callback(null);
          });
        }
      });
    }
  });
};

如您所见,我将所有错误回调到控制器,然后将其作为内部服务器错误处理。我处理数据库,文件系统可能的错误,我的代码中有太多的重复。我认为这是糟糕的设计,很难在生产中支持。请帮帮我。

1 个答案:

答案 0 :(得分:4)

当你说“厌倦了所有这些条件”时,我假设你正在谈论所有嵌套的回调以及那种直接嵌套回调导致的“屏幕右侧游行”?如果我假设不正确请澄清你的问题,我会删除我要写的所有不相关的内容。 : - )

避免else结构的一种便宜方法是代替

if(err) callback(err); 
else { ... stuff ... }

是这样做的:

if(err) return callback(err);

注意返回:导致函数执行结束,没有人关心回调的返回值,所以它们会被忽略。所以这可能会消除一层大括号。

为了更好地处理这个问题,您需要查看某种异步帮助程序。这些事情有三大类:

  1. 帮助管理多个回调序列的库,
  2. Promises,它允许您将异步操作表示为对象,或
  3. 隐藏详细信息的语言支持。
  4. 三种不同类型的库的示例包括stepflowasync作为帮助库,对于Qwhen.js的承诺,以及对于语言支持,请查看streamline

    有关详细信息,我在一年前就这个话题进行了演讲; slides are here也有a recording of the presentation