处理promisses和服务器响应的正确方法
我正在尝试改进我在node.js / sail.js中的代码,并且正在与promisses中的服务器响应作斗争。
当你看到第一.then
功能,您可以看到该方法返回false
的情况下forbidden access
或notFound
。 然后,在接下来的.then
函数中,我必须检查返回类型是否为=== false
以跳过部分并避免发送两次http头。 这能某种程度上提高了,跳过所有未来.then
万一失败的方法呢? 我可以抛出一个异常进入最后一个.catch
但是必须有一个case
在所有可能的状态之间切换。 (即禁止,serverError甚至找不到)
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.'});
})
如果我这样做,首先我分开逻辑和接收/发送功能。 其次我指定错误代码的列表。 它会是这样的:
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);
}
});
}
};
在我使用开关的情况下,我认为这是更好的方法来选择正确的响应,但在这个时候我没有任何想法
看看如何在Bluebird中实现过滤.catch()
- 在你的情况下,抛出所需的所有错误,但避免在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 a.b.c.d();
}).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
处理程序。