function convertRssIntoJson (rssFeed) {
console.log(rssFeed);
return feed.load(rssFeed, function(err, rss){
if(err) {
console.log("Error: ${err}");
return;
}
console.log(rss)
return rss;
});
};
Часть кода выше является обратным вызовом.Под капотом feed.load является асинхронным, что делает ваш обратный вызов выполненным асинхронно.
Теперь, когда вы вызываете свою функцию следующим образом:
let rssAsJsonData = convertRssIntoJson(rssFeed);
ваш rss
объект внутри convertRssIntoJson
пока не имеет значения, поскольку обратный вызов до сих пор не заполнен.Вот откуда взялись ваши undefined
.
Сами обратные вызовы не делают код асинхронным по умолчанию, но NodeJS работает с неблокирующей моделью ввода-вывода и, поскольку feed.load является вызовом ввода-вывода, он будетвыполняется асинхронно.
У вас есть несколько вариантов, но я перечислю только два.Не очень хорошее и приятное решение:
1) Не очень хороший способ исправить это - добавить обратный вызов в качестве аргумента к вашей функции convertRssIntoJson
и передать значение этого * 1017.* объект вверх по течению.Не очень хороший полный код можно найти ниже:
const feed = require('rss-to-json');
exports.handler = async (event) => {
let rssFeed = event.queryStringParameters.rssFeed;
convertRssIntoJson(rssFeed, (err, data) => {
if (err) {
return sendRes(500, { message: 'There was an err: ' + err.message })
}
return sendRes(200, data)
})
};
const sendRes = (status, body) => {
var response = {
isBase64Encoded: true | false,
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: body,
};
return response;
};
const convertRssIntoJson = (rssFeed, callback) => {
console.log(rssFeed);
feed.load(rssFeed, function (err, rss) {
if (err) {
console.log("Error: ${err}");
callback(err, undefined)
}
console.log(rss)
callback(undefined, rss)
});
};
2) Это хорошее, чистое, элегантное и рекомендуемое решение.Оберните ваш обратный вызов в Promise, как это
function convertRssIntoJson(rssFeed) {
console.log(rssFeed);
return new Promise((res, rej) => {
feed.load(rssFeed, function (err, rss) {
if (err) {
console.log("Error: ${err}");
return rej(err)
}
console.log(rss)
return res(rss)
});
})
};
Поскольку ваш обработчик async
, это означает, что он может просто await
на Promises.
Таким образом, ваш код клиента теперьпросто как:
return sendRes(200, await convertRssIntoJson(rssFeed));
Ваш окончательный код будет выглядеть так (я немного изменил рефакторинг для использования функций стрелок):
const feed = require('rss-to-json');
exports.handler = async (event) => {
let rssFeed = event.queryStringParameters.rssFeed;
return sendRes(200, await convertRssIntoJson(rssFeed));
};
const sendRes = (status, body) => {
var response = {
isBase64Encoded: true | false,
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: body,
};
return response;
};
const convertRssIntoJson = (rssFeed) => {
console.log(rssFeed);
return new Promise((res, rej) => {
feed.load(rssFeed, (err, rss) => {
if (err) {
console.log("Error: ${err}");
return rej(err)
}
console.log(rss)
return res(rss)
});
})
};
Если вы хотите узнать больше об асинхронности/ await, вы можете увидеть это в здесь .
EDIT : рефакторинг кода и код, добавленный для решения 1)