Node.js异步回调工厂

时间:2013-11-29 11:41:10

标签: node.js api rest express

我正在使用Node.js,Express和MySql开发 RESTful API 。没有使用ORM。

我想尽可能多地重用代码来处理资源请求。

我将实施一个回调工厂,我想听听您的方法。

api.js

这是主要的应用程序文件。

'use strict';

var
  http = require('http'),
  express = require('express'),
  app = express(),

  env = app.get('env'),
  config = require('./config')[env],
  pool = require('./pool')(config.database), /* node-mysql pool */

  people = require('./routes/people')(pool); /* route handlers for people resource */

app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);

app.get('/people', people.findAll); /* middleware handling request for the resource */

http.createServer(app).listen(8000);

路由/ people.js

这是包含处理/people资源请求的代码的文件。

'use strict';

module.exports = {
  var
    async = require('async'),
    CallbackFactory = require('../CallbackFactory'),
    people = {};

  people.findAll = function (req, res, next) {
    async.waterfall(
      [
        CallbackFactory.createCallback('getPoolConnection', pool),
        CallbackFactory.createCallback('lastQuery', 'SELECT * FROM person'),
        CallbackFactory.createCallback('json', res)
      ],
      CallbackFactory.getCallback('next', next);
    );
  };

  return people;
};

CallbackFactory.js

模块仅导出createCallback方法。

createCallback的第一个参数始终是回调名称 其他参数特定于要创建的回调。

'use strict';

var
  factoryMethods: {
    getPoolConnection: function (pool) {
      return function (callback) {
        pool.getConnection(function (err, connection) {
          callback(err, connection);
        };
      };
    },
    lastQuery: function (sql, values) {
      return function (connection, callback) {
        connection.query(sql, values, function (err, result) {
          connection.release();
          callback(err, result);
        });
      };
    },
    json: function (res) {
      return function (result, callback) {
        res.json(result);
        callback();
      };
    },
    next: function (next) {
      return function (err) {
        if (err) {
          return next(err);
        }
      };
    },
  };

module.exports = {
  createCallback: function () {
    var
      args = Array.prototype.slice.call(arguments),
      name = args.shift();

    return factoryMethods[name].apply(null, args);
  }
};

结论

我用Google搜索并搜索了SO,以便找到对代码重用有用的方法 我没找到任何东西。也许这不是正确/最好的方法。 您如何看待它?

1 个答案:

答案 0 :(得分:0)

我认为你在这里走错了路。回调工厂不是一种常见的模式,因为它增加了一层抽象而不会以任何方式降低复杂性。换句话说,将async.waterfall视为已经提供了您正在寻找的抽象层。或者,如果您喜欢命名函数,我建议使用async.auto,它还会根据您指定的依赖关系自动确定哪些函数可以串行和并行运行。

我建议让async.waterfall或async.auto直接调用你的函数。如果您想要额外的抽象和更少的代码,请使用像Sequelize这样的ORM。但我发现你的工厂对于后来遇到的其他人的代码的理解变得复杂。