首页 > 解决方案 > 在函数内部定义外部范围变量

问题描述

我正在为表单的字段服务器端(expressjs)之一构建验证并为此执行以下操作:

  1. 从 json 文件中读取数据

  2. 从中获取属性(数组)

  3. 检查它是否包含用户生成数组的每个元素,仅此而已,例如:

[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,所以这意味着包含函数返回未定义(我测试过)

那么这有什么线索呢?谢谢!

标签: javascriptarraysnode.jsjsonexpress

解决方案


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(...)


推荐阅读