我正在研究一个nodejs代码,该代码从站点获取数据,对其进行解析,查找特定数据并为先前获取的数据获取其他内容。但是最终的return语句将返回而不会从第二个API调用中获取值。
我尝试实现异步等待,但是我不确定该把它们准确放在哪里。
const getMainData = async val => {
let result = [];
//get xml data from the API
const xmlData = await getSiteContent(`value`); //axios call
parseString(xmlData, (err, json) => { //convert xml to json
const { entry } = json.feed; // array of results.
result = entry.map(report => {
const secondInfo = getSomeMoreData(report.something); //axios call
const data = {
id: report.id,
date: report.date,
title: report.title
};
data.info = secondInfo;
return data;
});
});
return { result };
};
我期望函数返回具有ID,日期,标题和信息的数组 result 。但是我将 info 设置为null,因为它将转到另一个执行另一个API调用的函数。
答案 0 :(得分:1)
尝试将parseString
包装在promise
中,以便可以await
的结果,然后使entry.map
回调具有async
函数,以便可以使用await
关键字来等待axios提取的结果。
async function xml2json(xml) {
return new Promise((resolve, reject) => {
parseString(xml, function (err, json) {
if (err)
reject(err);
else
resolve(json);
});
});
}
const getMainData = async val => {
//get xml data from the API
const xmlData = await getSiteContent(`value`); //axios call
const json = await xml2json(xmlData);
const { entry } = json.feed; // array of results
const result = await Promise.all(
entry.map(async report => {
const secondInfo = await getSomeMoreData(report.something); // axios call
const data = {
id: report.id,
date: report.date,
title: report.title,
};
data.info = secondInfo;
return data;
})
)
return { result };
}
让我知道是否可行。如果没有,我可以尝试进一步帮助您。
答案 1 :(得分:1)
您的代码存在的问题是您将混合诺言概念(异步/等待是一种语法糖-同样)与回调概念一起使用。
并且return语句位于parseString()的callback()之外,并且仅在parseString()是异步函数的情况下,才可能在返回结果之后执行回调。
因此,在以下解决方案中,我将parseString()封装在一个promise中,以便可以等待它。
const parseStringPromisified = async xmlData => {
return new Promise((resolve, reject) => {
parseString(xmlData, (err, json) => {
if (err) {
reject(err);
}
resolve(json);
});
});
};
const getMainData = async val => {
//get xml data from the API
const xmlData = await getSiteContent(`value`); //axios call
const json = await parseStringPromisified(xmlData);
const { entry } = json.feed; // array of results.
const result = entry.map(async report => {
const secondInfo = await getSomeMoreData(report.something); //axios call
return {
id: report.id,
date: report.date,
title: report.title,
info: secondInfo
};
});
return Promises.all(result);
};