使用SQL数组执行Axios请求



我试图在Express路由内查询mySQL数据库,得到一个名为"受试者";,然后使用数组运行axios请求。然后我想在EJS上显示响应。

// for-each "subject", 
var url = `http://news.com/${subject}`
const articles_get =await axios.get(url)
res.render('news',{articles:articles_get.data.articles})

我尝试了太多的事情,我总是在";async/await必须处于顶层";以及";HEADERS ALREADY SENT";。我在SO上尝试了其他例子,但都没有成功。我想我错过了一些想法。请提供任何帮助,我们将不胜感激!

这是我当前的代码,上面写着";SyntaxError:await仅在异步函数和模块的顶层主体中有效;我试图将函数移出路由,然后在路由内调用它,但它始终没有返回任何内容。

app.get("/mySubjects", (req, res) => {
var subjects = [];
var username = req.body["username"];
connection.query(
"SELECT * FROM mySubjects WHERE username = ?",
[username],
async function (error, results, fields) {
if (error) {
throw error;
}
if (results.length > 0) {
results.forEach((result) => {
subjects.push(result.subject);
});
subjects.forEach((subject) => {
//call NEWS API FOR EACH SUBJECT
try {
var url = `https://newsapi.org/v2/top-headlines/sources?category=${subject}apiKey=c7777777777777`;
const news_get = await axios.get(url);
res.render("news", { articles: news_get.data.articles });
} catch (error) {
if (error.response) {
console.log(error);
}
}
});
} else {
res.status(401).send({ message: "Nothing is here." });
}
}
);
});

您只能调用res.render()一次,因为它将呈现您的模板并响应客户端。您需要做的是首先收集所有数据,然后渲染模板。

例如

if (results.length > 0) {
// using Promise.allSettled so it doesn't bail at the first failed request
const allResults = await Promise.allSettled(
results.map(async ({ subject }) => {
const { data: { articles } } = await axios.get("https://newsapi.org/v2/top-headlines/sources", {
params: { // params is the easy way to pass query parameters
category: subject,
apiKey: "c7777777777777",
}
});
return { subject, articles };
})
);
// Extract all the successful responses
const allArticles = allResults
.filter(({ status }) => status === "fulfilled")
.map(({ value }) => value);
// render your template
res.render("news", { allArticles });
// optionally log the failed requests
allResults
.filter(({ status }) => status === "rejected")
.forEach(({ reason }) => {
console.error(reason.response?.data ?? reason.message)
})
} else {
// 401 is for Unauthorized, use 404 for Not Found
res.status(404).send({ message: "Nothing is here." });
}

这将呈现news模板,传递名为allArticles的属性,该属性是具有subjectarticles属性的对象数组。

您不应该在forEach内部发送响应,因为它还没有完成迭代。

下面的示例将以数组的形式返回所有response.data,并确保在ejs文件中相应地处理它们。

app.get('/mySubjects', (req, res) => {
const username = req.body['username'];
connection.query(
'SELECT * FROM mySubjects WHERE username = ?',
[username],
function (error, results, fields) {
if (error) throw error;
if (results.length > 0) {
const requests = results.map(({ subject }) =>
axios.get(
`https://newsapi.org/v2/top-headlines/sources?category=${subject}apiKey=c7777777777777`,
),
);
Promise.all(requests)
.then((news) => {
res.render('news', { news });
})
.catch((err) => {
// Handle error
console.log(err.message);
});
} else {
res.status(401).send({ message: 'Nothing is here.' });
}
},
);
});

最新更新