处理promisses和服务器响应的正确方法

我正在尝试改进我在node.js / sail.js中的代码,并且正在与promisses中的服务器响应作斗争。

当你看第一个.then函数时,你可以看到该方法在forbidden accessfalse的情况下返回false 。 然后,在接下来的函数中,我必须检查返回types是否为=== false以跳过部分并避免发送两次http头。 这可以改善某些方面,跳过所有的下一个方法,如果失败的话? 我可以抛出一个exception进入最后一个.catch但必须有一个case之间切换所有可能的状态。 (即禁止,serverError甚至没有find)

 Notification.findOne({id: req.param('id')}) .then(function(notification) { if (!notification) { res.notFound(); return false; } if (notification.triggeredBy != req.session.user.id) { res.forbidden(); return false; } return notification; }) .then(function(notification) { if (notification === false) { return false; } return Notification.update(notification.id, actionUtil.parseValues(req)); }) .then(function(notification) { if (notification === false) { return false; } res.json(notification); }) .catch(function(err) { sails.log(err); res.serverError({message: 'A server error occurred.'}); }) 

如果我这样做,首先我分开逻辑和接收/发送function。 其次我指定错误代码的列表。 这将是这样的:

NotificationService.js

 /* Listing of error codes: { * [1] Object not found * [2] Forbidden * [3] Server error } */ module.exports = { nameOfMethod: function(ID, sessionID) { return new Promise(function(resolve, reject) { Notification.findOne({ id: ID }) .then(function(notification) { if (!notification) return reject({ error_code: 1 }); if (notification.triggeredBy !== sessionID) return reject({ error_code: 2 }); Notification.update(notification.id, actionUtil.parseValues(req)) .then(function(notification) { return resolve(notification); // finally return our notification }) .catch(function(err) { sails.log.error(err); // It's good when log is classified. In this case is error return reject({ message: 'A server error occurred.' }); }); }) .catch(function(err) { sails.log.error(err); return reject({ message: 'A server error occurred.' }); }); }); } }; 

NotificationController.js

 module.exports = { notifyMe: function(req, res) { const ID = req.param('id'), sessionID = req.session.user.id; NotificationService.nameOfMethod(ID, sessionID) .then(function(notification) { return res.send(notification); }) .catch(function(err) { switch (err.error_code) { case 1: return res.notFound(err); case 2: return res.forbidden(err); default: return res.serverError(err); } }); } }; 

在我使用开关的情况下,我认为这是更好的方法来select正确的响应,但在这个时候我没有任何想法

看看如何过滤.catch()在Bluebird中实现 – 在你的情况下,抛出你需要的所有错误,但避免在catch处理程序中有一个大的开关/

 .catch( class ErrorClass|function(any error)|Object predicate..., function(any error) handler ) -> Promise .caught( class ErrorClass|function(any error)|Object predicate..., function(any error) handler ) -> Promise 

这是一个扩展.catch更像在Java或C#等语言中的catch-clause。 而不是手动检查instanceof或.name ===“SomeError”,您可以指定一些错误构造函数,这些错误构造函数可以用于这个catch处理程序。 首先遇到的具有符合条件的构造函数的catch处理程序将被调用。

例:

 somePromise.then(function() { return abcd(); }).catch(TypeError, function(e) { //If it is a TypeError, will end up here because //it is a type error to reference property of undefined }).catch(ReferenceError, function(e) { //Will end up here if a was never declared at all }).catch(function(e) { //Generic catch-the rest, error wasn't TypeError nor //ReferenceError }); 

请参阅: http : //bluebirdjs.com/docs/api/catch.html#filtered-catch

代替:

 return false; 

您可以使用:

 return Promise.reject(someReason); 

要么:

 throw someReason; 

你不必检查那些false值 – 只要使用(可能是多个) catch处理程序。