Xml2js не возвращает проанализированный JSON

Что мне здесь не хватает? JSON не возвращается из метода parseXML, хотя console.info работает правильно. Вместо этого он возвращает undefined.

function parseXML(){

  var parseString = require('xml2js').parseString;

 var str= '<Customers>\
  <Customer>\
      <first>JIM</first>\
      <last>BEAM</last>\
      <address>22. JIM. RD.</address>\
      <age>24</age>\
      <age2>2.0</age2>\
      <Phone>206-555-0144</Phone>\
  </Customer>\
</Customers>'

parseString(str, function (err, result) {
  console.info(JSON.stringify(result));  //<<<<<<<RETURNS THE JSON I EXPECTED
  return JSON.stringify(result);
});
}

app.get('/*', (request, response) => {
  var json=parseXML();
  console.info(json)     //<<<<<<RETURNS UNDEFINED
  var obj=JSON.parse(json);
  console.info(obj);
  var jsonres= obj.Customers.Customer[0]["first"];

  response.send(['Hello from Express!',jsonres])
})

return из обратного вызова не возвращается во внешнюю функцию

charlietfl 10.04.2019 21:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
242
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в том, что результат parseString возвращается асинхронно, но вы не обрабатываете вызов функции и его результат асинхронно.

Возможно, вы захотите узнать, как асинхронное программирование и обратные вызовы работают в Node.js и JavaScript.

Ответ принят как подходящий

вы можете заставить это работать с обещанием и async/await:

function parseXML() {

var parseString = require('xml2js').parseString;

  var str = '<Customers>\
  <Customer>\
      <first>JIM</first>\
      <last>BEAM</last>\
      <address>22. JIM. RD.</address>\
      <age>24</age>\
      <age2>2.0</age2>\
      <Phone>206-555-0144</Phone>\
  </Customer>\
</Customers>'
return new Promise((resolve, reject) => {
  parseString(str, function (err, result) {
    console.info(JSON.stringify(result));  //<<<<<<<RETURNS THE JSON I EXPECTED
    resolve(JSON.stringify(result))
  });
})
}

app.get('/*', async (request, response) => {
  var json = await parseXML();
  console.info(json)     //<<<<<<RETURNS UNDEFINED
  var obj = JSON.parse(json);
  console.info(obj);
  var jsonres = obj.Customers.Customer[0]["first"];

  response.send(['Hello from Express!', jsonres])
})

Обновлено: Извините, я думаю, мне следует добавить здесь некоторые пояснения.

Функция parseString имеет асинхронный обратный вызов, который не срабатывает до тех пор, пока функция не завершит обработку, поэтому причина, по которой ваш код не работает, заключается в том, что вы пытаетесь получить доступ к данным до завершения их обработки. вот шаги, которые происходят:

  1. вызвать функцию parseXML
  2. вызвать функцию parseString (это запускает асинхронную обработку)
  3. попробуйте и зарегистрируйте данные, хранящиеся в переменной json, которая должна содержать результат вызова parseXML. это не определено, потому что функция parseXML ничего не возвращает, поэтому undefined регистрируется в консоли. Ваше возвращаемое значение в обратном вызове parseString возвращает значение из функции обратного вызова, а не исходной функции. Кроме того, он даже не вызывается до тех пор, пока вы не попытаетесь получить доступ к данным в переменной json.
  4. функция обратного вызова, переданная функции parseString, завершается, и вы видите ожидаемый json, зарегистрированный в консоли.

Мои изменения в основном заключают ваш parseString в обещание, которое разрешается после завершения обратного вызова и возвращает это обещание из функции parseXML. Это позволяет использовать async/await для получения результата асинхронной обработки. можно еще написать parseXML().then(data => { //process data here }

Спасибо за подробное объяснение - это было невероятно полезно!

Rilcon42 10.04.2019 21:33

Рад, что смог быть полезен!

Mike 10.04.2019 22:20

Другие вопросы по теме