我正在使用带有check()和audit-check-arguments包的流星。
当我使用流星方法通过async / await并传递参数时,即使我使用check()来验证函数参数,审计包仍会引发异常,指示并非所有输入参数都已被检查。如果我删除了异步/等待实现,则该程序包无法放入婴儿床。我想念什么?
示例:
Meteor.methods({
test: async function(param1){
check(param1, String);
...
await ....
}
});
引发异常:
=> Client modified -- refreshing
I20200513-10:43:27.978(5.5)? Exception while invoking method 'test' Error: Did not check() all arguments during call to 'test'
I20200513-10:43:27.979(5.5)? at ArgumentChecker.throwUnlessAllArgumentsHaveBeenChecked (packages/check/match.js:515:13)
而这种传统的流星方法不会抛出任何异常
Meteor.methods({
test: function(param1){
check(param1, String);
...
}
});
我确定我确实传递了一个参数。
似乎audit-argument-checks
仅适用于同步功能。
我没有这个问题,因为我们使用mdg:validated-method
,它需要您为每个方法指定一个参数验证器。
它通过将方法函数包装为此来关闭参数检查器:
mdg:validated-method
我能想到的最简单的解决方案是将检查与异步功能分开。您可以使用包装器函数执行此操作:
// Silence audit-argument-checks since arguments are always checked when using this package
check(args, Match.Any);
或者您甚至可以通过异步IIFE内联完成它:
function checkAndRun(check, run) {
return function(...args) {
check.apply(this, args);
return run.apply(this, args);
}
}
Meteor.methods({
'example': checkAndRun(
function(exampleID){
check(exampleID, String);
},
async function(exampleID) {
const result = await doSomethingAsync(exampleID);
SomeDB.update({ _id: exampleID }, { $set: { someKey: result.value } });
return result.status;
}
}
});
哪个,想起来,比起初我想到的最简单的解决方案要简单得多
您只想以某种方式将同步检查与异步方法主体分开
如果您感到好奇,请深入研究源代码以查看其来源。当方法被调用时(在Meteor.methods({
example(exampleID) {
check(exampleID, String);
return (async () => {
const result = await doSomethingAsync(exampleID);
SomeDB.update({ _id: exampleID }, { $set: { someKey: result.value } });
return result.status;
})()
}
});
中),我们在这里结束,同步方法调用了ddp-server/livedata-server
的第一个引用:audit-argument-checks
将我们带到https://github.com/meteor/meteor/blob/master/packages/ddp-server/livedata_server.js#L1767-L1770进行此处的另一个同步呼叫:check/Match
[使用了奇怪的https://github.com/meteor/meteor/blob/71f67d9dbac34aba34ceef733b2b51c2bd44b665/packages/check/match.js#L114-L123构造,它在内部有另一个同步调用:Meteor.EnvironmentVariable