简体   繁体   中英

Node.js async callback factory

I'm developing a RESTful API with Node.js, Express and MySql. No ORM used.

I want to reuse as much code as possible in order to handle requests for resources.

I'm going to implement a callback factory and I'd like to hear from you about my approach.

api.js

It is the main application file.

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

routes/people.js

It is the file containing code to handle requests for /people resource.

'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

The module exports the createCallback method only.

The first argument to createCallback is always the callback name.
Other arguments are specific to the callback to create.

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

Conclusion

I googled and searched SO in order to find approaches that are useful to code reuse.
I didn't find anything. Maybe it is not the correct/best approach. What do you think about it?

I think you're on the wrong track here. Callback factory is not a common pattern because it's adding a layer of abstraction without reducing complexity in any way. Phrased differently, think of async.waterfall as already providing the abstraction layer that you're looking for. Or, if you like named functions, that I recommend async.auto , which also automatically determines which functions can operation in serial and parallel based on the dependencies you specify.

I would recommend having async.waterfall or async.auto call your functions directly. If you want additional abstraction and less code, use an ORM like Sequelize. But I see your factory complicating understanding your code for anyone else who comes along later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM