javascript - 在函数内部定义外部范围变量
问题描述
我正在为表单的字段服务器端(expressjs)之一构建验证并为此执行以下操作:
从 json 文件中读取数据
从中获取属性(数组)
检查它是否包含用户生成数组的每个元素,仅此而已,例如:
[1,2,3,4,5]; (json array)
[1,2,3,4,5,6] (user generated array) //must return false
[1,2,3,4,5];
[1,3,4] //must return true;
[1,2,3,4,5];
[1,2,7] //must return false;
所以我为此使用此代码:
const contains = (arr1, arr2) => {
arr2.every(v => arr1.indexOf(v) !== -1)
}
var match;
fs.readFile('../tags.json', 'utf8', (err, data)=>{
var JsonData = JSON.parse(data);
var tagsArray = JsonData.tags;
console.log(tagsArray)
console.log(tags)
if(tagsArray instanceof Array){
console.log('tagsArray is array')
}
if(!contains(tagsArray, tags)){
match = false
}
else{
match = true
}
console.log(match + ' blah1')
});
console.log(match + ' blah2')
if(match == false){
return res.status(409).send({
message: 'Do not provide your own tags'
});
}
但它总是在块内返回false,fs.readFile
因为它在块外返回未定义fs.readFile
,所以这意味着包含函数返回未定义(我测试过)
那么这有什么线索呢?谢谢!
解决方案
fs.readFile
是异步的,因此任何取决于其结果(正在读取的文件)的代码都需要进入您的回调函数。(回调函数是其中的(err, data) => { ... }
一部分。)
移动回调内部的console.log(match + 'blah2')
andif(match == false) { ... }
部分(在 blah1 行之后)。
您还可以查看async或使用fs.readFileSync这将允许您避免使用回调函数。
另一个方面,你会想要确保你总是到达一条res.send()
线,即match == true
在你的情况下。否则,当匹配为真时,您的 http 请求将不会返回。
编辑:
这是一个非常基本的 express 结构,主要是伪代码和注释,只是为了说明回调:
app.post('/tags', (req, res) => {
// your setup code here
fs.readFile('../tags.json', 'utf8', (err, data) => {
console.log('readFile has finished')
// now you have heard back from readFile
// check the err and send 500 if there was a problem
// otherwise work with the file in the var data
// any other db-related stuff also goes in here, which probably
// has its own callback you need to use
db.save(data, (err) => {
// db call is done, potentially with an error
// Here you can use `res` to send http response
})
// !! again here the db is still doing its work
})
// !! anything you add here will be executed before readFile is done
console.log('readFile is probably still at work')
})
我还应该指出,您要contains
返回 bool 值,即return arr2.every(...)
推荐阅读
- python - 尝试使用 python 将 kdb 转换为 csv,除一列外,所有内容都正确转换
- spring - 当@Controller 中的方法是最终方法时,@Autowired 变量为空
- java - 排序对象的对象
- c++ - 无法使用 Lua 中的 C++ 模块
- ios - 如何将 ViewController 呈现为具有透明背景的弹出式 VC?
- twilio - 想要使用 twilio javascript SDK 创建出站电话会议
- html - 带有post方法的Laravel表单未提交
- sql-server - SSIS - 更改列名的 Excel 到 SQL Server
- jquery - 如何应用 .each 隐藏所有实例,使用 jquery 在 TD 中查找文本
- java - 有没有办法使用 Java 代码而不是外部程序从 XML 模式创建 .java 类?