正确处理Mongoose的提取错误?

这是一个纯粹的最佳实践问题。 我对Node和Mongoose很新。 我非常喜欢这项技术,并且一直在开发一个项目,为我正在构build的应用程序构build一个支持JSON的API。

当我从数据库中获取对象时,我发现我不断重复代码。 例如:

Playlist.findById(req.params.id, function(err,playlist){ if (err) return res.json({error: "Error fetching playlist"}); else if (!playlist) return res.json({error: "Error finding the playlist"}); //Actual code being performed on the playlist that I'm fetching }); 

函数调用顶部的error handling是烦人的,因为我不得不重复每个调用数据库的代码…所以我想。

我想过使用callback如:

 var fetchCallback = function(err,objOrDoc,callback){ //Handle the error messages callback(objOrDoc); }; 

但是,这种方法会搞乱我的顺序stream程,因为在执行提取之前我必须定义callback函数。 所以,如果我有很多数据库查询链接在一起,我将不得不按照相反的顺序放置callback,这在干净的编码方面是远远不够的。

我想知道是否有人遇到这个问题,并有任何减less重复的最佳做法。

我也使用快速框架,所以如果有一个有用的方法来处理它,我也有兴趣知道。

有一些有趣的方法可以在这里尝试。

最简单的,你可以简单地有一个函数,加载一个对象,并在出错的情况下处理输出。

 fetchResource = function(model, req, res, callback) { model.findById(req.params.id, function(err, resource) { if (err) return res.json({error: "Error fetching " + model.toString()}); else if (!playlist) return res.json({error: "Error finding the " + model.toString()}); callback(resource); }); }; app.on('/playlists/1', function(req, res) { fetchResource(Playlist, req, res, function(playlist) { // code to deal with playlist. }); }); 

这还是相当多的重复,所以我可能会尝试将其转移到中间件中 。

路由中间件

路由可以通过向该方法传递一个或多个额外的callback(或数组)来利用路由特定的中间件。 此function对于限制访问,加载路由等使用的数据非常有用。

现在我还没有testing过这个,有点儿手动(读取:伪代码),但我认为它应该是一个体面的例子。

 // assuming a URL of '/playlist/5' or '/user/10/edit', etc. function loadResource(model) { return function(req, res, next) { model.findById(req.params.id, function(err, resource) { if (err) return res.json({error: "Error fetching " + model.toString()}); else if (!resource) return res.json({error: "Error finding the " + model.toString()}); req.resource = resource; next(); }); } } app.get('/playlist/:id', loadResource(Playlist), function(req, res) { var playlist = req.resource; ... }); app.get('/user/:id', loadResource(User), function(req, res) { var user = req.resource; ... }); 

快速源代码包含了这种模式的一个很好的例子, 文档中的中间件部分 (具体在“路由中间件”下)详细介绍了它。