我有一个方法getModel(kind)
,它返回NodeJS中的数据存储区数据模型。
我在getModel(kind)
方法中创建了一个简单的类型-o,并发现了一个未被捕获的拒绝承诺的潜在问题。
如何在将来更新代码以捕获这些未捕获的异常?
调用getModel:
//Save the data to the database
getModel('transferrequest').create(TransferRequestNew, (err, savedData) => {
if (err) {
console.log('Transfer Request New unable to create new entity. Error message: ', err);
next(err);
return;
}
console.log('savedData: ', savedData);
res.redirect(`${req.baseUrl}/history`);
});
getModel函数:
function getModel(kind) {
const model = __modelsdir+'/model-'+__databackend+kind;
return require(model);
}
使用getModel.create
调用创建方法:
function create (data, cb) {
update(null, data, cb);
}
未处理错误:
(node:31937)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误:找不到模块'/ mypath / projectname / models / model-datastoretransferrequest'
答案 0 :(得分:3)
首先,我会说动态require
是一种让自己陷入困境的方法。让我将我的答案分为两部分,重点说明应该避免的原因并提出一些解决方案。
运行时的同步加载
require
是一个同步操作,众所周知,这些操作会阻止事件循环。想象一下,相对大量的用户同时使用您的应用程序,并且环路延迟超过合理值或者至少会导致性能问题。
难以测试此类动态模块
如果没有适当的测试覆盖率,您如何保证您的应用程序足够稳定?对于动态需求,它变成了一项非常重要的任务。这导致另一个问题 - 你真的有这么多的数据模型需要动态创建和加载吗?如果没有,您可以使用定义明确且明确要求的数据模型使您的工作更加舒适,而不是“神奇”加载容易出错。而且,不要忘记循环依赖和其他可怕的可憎行为,在进口时刻之前它们将一直保持沉默。
此类应用程序的总体设计
值得在global-require
上阅读ESLint topic,并了解为什么默认情况下不允许在各种规则集中使用它(例如Airbnb)。但你实际上自己提到过:
我在
getModel(kind)
方法中创建了一个简单的类型o并且发现了一个 未被捕的承诺拒绝的潜在问题。
如果这足以打破您的应用程序,那么这个应用程序是否可以被认为是健壮的?它与raw strings作为参数是一样的:一个应该使它们成为常量或者作为函数本身出现,摆脱难以调试的运行时错误,以换取启动时的简单语法错误。
< / LI> 醇>明确要求的模型
创建明确定义的对象结构,表示数据结构并从一个聚合的index.js
文件中显式加载它们:
// models/transfer-request.js
class TransferRequest {
create(instance, cb) {
// Implementation...
}
}
module.exports = TransferRequest;
// models/index.js
const TransferRequest = require('./transfer-request.js');
// Other models requires...
module.exports = {
TransferRequest,
// Other models exports...
};
使用Factory 创建实例:
如果您仍想坚持使用与现在类似的东西,请使用标准模式创建模型工厂:
class ModelFactory {
constructor(model){
switch(model) {
case 'transferrequest':
// Implementation of TransferRequest object creation...
break;
case 'othertransferrequest':
// Implementation of OtherTransferRequest object creation...
break;
default:
throw new Error('Unknown class');
}
}
}
以清晰可见的方式创建实际模型对象的时间和次数,在代码中定义明确,而不是通过动态加载来模糊可能的选项。
是的,如果您仍希望在运行时require
,请使用try/catch
来处理拒绝。
答案 1 :(得分:0)
这只是解决方法的一个小方法,但可能有一些更好的方法。为什么不尝试 - 捕获require语句?我测试了这个,这很好用:
function getModel(kind, cb) {
var model = __dirname + kind;
try {
var requiredModel = require(model);
return cb(null, requiredModel)
}
catch (e) {
return cb(new Error("model not found!"), null);
}
}
我已经使用__dirname
对此进行了测试,但这不会产生任何影响。