определить переменную внешней области видимости внутри функции - PullRequest
1 голос
/ 18 мая 2019

Я создаю проверку для одного из серверных полей формы (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, то есть это означает, что функция возвращает функцию undefined (я проверял это)

так в чем же ключ? Спасибо!

Ответы [ 2 ]

1 голос
/ 18 мая 2019

fs.readFile является асинхронным, поэтому любой код, который зависит от его результата (читаемого файла), должен находиться внутри функции обратного вызова. (Функция обратного вызова - это (err, data) => { ... } часть.)

Перемещение частей console.log(match + 'blah2') и if(match == false) { ... } внутри функции обратного вызова (после строки blah1).

Вы также можете посмотреть async или использовать fs.readFileSync , который позволит вам избежать использования функций обратного вызова.

Еще одна побочная точка, вам нужно убедиться, что вы всегда достигаете линии res.send(), т.е. когда match == true в вашем случае. В противном случае ваш http-запрос не вернется, когда совпадение будет истинным.

Edit:

Вот действительно базовая структура для выражений, в основном псевдокодов и комментариев, просто для иллюстрации обратных вызовов:

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

0 голосов
/ 12 июня 2019

Вы можете использовать async / await :

async function read(){
let data = await fs.readFile(<path>);
console.log(data); //You can use data everywhere within this scope
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...