Node.js API中的异步函数没有按预期工作



作为练习,我将创建一个简单的API,允许用户提供搜索词来检索到资源集合中适当新闻文章的链接。相关函数和使用该函数的路由处理程序如下:

function GetArticles(searchTerm) {
const articles = [];
//Loop through each resource
resources.forEach(async resource => {
const result = await axios.get(resource.address);
const html = result.data;
//Use Cheerio: load the html document and create Cheerio selector/API
const $ = cheerio.load(html);
//Filter html to retrieve appropriate links 
$(`a:contains(${searchTerm})`, html).each((i, el) => {
const title = $(el).text();
let url = $(el).attr('href');
articles.push(
{
title: title,
url: url,
source: resource.name
}
);
})
})
return articles; //Empty array is returned
}

和使用函数的路由处理程序:

app.get('/news/:searchTerm', async (req, res) => {
const searchTerm = req.params.searchTerm;
const articles = await GetArticles(searchTerm);
res.json(articles);
})

我得到的问题是返回的"文章"数组为空。但是,如果我没有循环遍历每个资源正如GetArticles开头所述,而是只对单个"资源"one_answers"文章"执行主要逻辑。与所请求的数据一起返回,且不为空。换句话说,如果函数如下:

async function GetArticles(searchTerm) {
const articles = [];
const result = await axios.get(resources[0].address);
const html = result.data;
const $ = cheerio.load(html);
$(`a:contains(${searchTerm})`, html).each((i, el) => {
const title = $(el).text();
let url = $(el).attr('href');
articles.push(
{
title: title,
url: url,
source: resources[0].name
}
);
})
return articles; //Populated array
}

那么"articles">

我确信这与我如何处理代码的异步特性有关。我试过刷新我在JS异步编程的知识,但我仍然不能完全修复功能。显然,这些"文章"数组在填充之前被返回,但是如何返回呢?

有人可以帮助解释为什么我的GetArticles功能与单个"资源";但是当循环遍历一个"资源"数组时就不一样了?

试试这个

function GetArticles(searchTerm) {
return Promise.all(resources.map(resource => axios.get(resource.address))
.then(responses => responses.flatMap(result => {
const html = result.data;
//Use Cheerio: load the html document and create Cheerio selector/API
const $ = cheerio.load(html);
let articles = []
//Filter html to retrieve appropriate links 
$(`a:contains(${searchTerm})`, html).each((i, el) => {
const title = $(el).text();
let url = $(el).attr('href');
articles.push(
{
title: title,
url: url,
source: resource.name
}
);
})
return articles;
}))

}

实现中的问题在这里resources.forEach(async resource...

你已经定义了async函数,但是当结果。Foreach get被执行并启动你的异步函数,它不会等待。

所以你的数组将永远是空的

最新更新