Что мне здесь не хватает? 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])
})
Проблема в том, что результат 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 имеет асинхронный обратный вызов, который не срабатывает до тех пор, пока функция не завершит обработку, поэтому причина, по которой ваш код не работает, заключается в том, что вы пытаетесь получить доступ к данным до завершения их обработки. вот шаги, которые происходят:
Мои изменения в основном заключают ваш parseString в обещание, которое разрешается после завершения обратного вызова и возвращает это обещание из функции parseXML. Это позволяет использовать async/await для получения результата асинхронной обработки. можно еще написать parseXML().then(data => { //process data here }
Спасибо за подробное объяснение - это было невероятно полезно!
Рад, что смог быть полезен!
return
из обратного вызова не возвращается во внешнюю функцию