作為一個練習,我正在創建一個簡單的 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 開頭所評論的那樣“回圈遍歷每個資源”,而是僅在單個“資源”上執行主要邏輯,則“文章”將與請求的資料一起回傳并且不為空。換句話說,如果函式如下:
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
}
然后“文章”不是空的,如預期的那樣。
我確信這與我如何處理代碼的異步特性有關。我已經嘗試重繪 我對 JS 中的異步編程的知識,但我仍然無法完全修復該功能。顯然,“articles”陣列是在填充之前回傳的,但是如何回傳呢?
有人可以幫助解釋為什么我的 GetArticles 函式適用于單個“資源”而不是在回圈“資源”陣列時?
uj5u.com熱心網友回復:
試試這個
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 但是當 result.foreach 被執行并啟動你的 async 函式時它不會等待。
所以你的陣列總是空的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/463936.html
