0

我在 Express 中设置了一条如下所示的路线:

app.get('/api/:type/:id', api.getItemById);

函数 api.getItemById 在路由的 api 模块中。但是在 api 模块中,我必须运行一个连接到数据库的函数,然后定义所有响应函数,如下所示:

couchbase.connect(dbConfiguration, function (err, bucket) {
  if (err) {
    throw (err)
  }

  exports.getItemById = function (req, res) {
    if (req.params.type == 'tag' || req.params.type == 'user' || req.params.type == 'asset' || req.params.type == 'expense' || req.params.type == 'income') {
      get(req, res, req.params.type);
    } else {
      res.send(400);
    }
  };

});

问题是在这种情况下,应用程序找不到 getItemById 函数并抛出:

.get() requires callback functions but got a [object Undefined]

我不确定我做得对。如果在回调函数中定义,您能否建议我如何使该函数对节点应用程序可见?

4

2 回答 2

1

简而言之:你不能。require是同步的并期望[module.]exports同步设置(在加载模块的那一刻)。

您可以使用一个模块范围的变量,该变量最初为false,并在设置true数据库后设置为 。您的路线处理程序可以检查:

var ready = false;

// connect to database
couchbase.connect(dbConfiguration, function (err, bucket) {
  if (err) {
    throw (err)
  }
  ready = true;
};

// export your route handler
exports.getItemById = function (req, res) {
  // check for readiness
  if (! ready)
    return res.send(500); // 'Internal Server Error', or any error you like

  // if ready, perform the regular action
  if (req.params.type == 'tag' || req.params.type == 'user' || req.params.type == 'asset' || req.params.type == 'expense' || req.params.type == 'income') {
    get(req, res, req.params.type);
  } else {
    res.send(400);
  }
};

如果您不想要这样的设置(可以在连接数据库之前处理请求),则需要推迟服务器(app.listen(...)或等效)的启动,直到完成所有异步启动操作。但这需要更多的努力。

于 2013-05-20T19:14:41.610 回答
0

你不能不导出getItemById;您应该导出一个初始化函数,该函数在设置数据库时在回调中传递该函数:

exports.init = function(callback) {
    couchbase.connect(dbConfiguration, function (err, bucket) {
      if (err) {
        throw (err)
      }

      var getItemById = function (req, res) {
        if (req.params.type == 'tag' || req.params.type == 'user' || req.params.type == 'asset' || req.params.type == 'expense' || req.params.type == 'income') {
          get(req, res, req.params.type);
        } else {
          res.send(400);
        }
      };

      callback(getItemById);
    });
}

然后require像这样执行:

require("api").init(function(getItemById) {
    // set up express...

   app.get('/api/:type/:id', getItemById);

   // ...
});
于 2013-05-20T20:11:28.453 回答