我正在使用 cheerio
和axios
从网页上获取所有链接,并通过axios
发出 GET 请求并检查每个链接是否为未损坏的链接(即 状态码为200 )。
然后,我想将每个断开的链接 URL 放入一个数组中。
我无法用async
和await
来解决这个问题。
const cheerio = require("cheerio");
// returns an array of broken link urls
async function getAllBrokenLinks(url) {
const res = await axios.get(url) // get webpage
// if there was an error getting the data, return null
if (!res || res.status != 200) {
return null;
}
let body = res.data.body.value; // get body html from res
let results = [];
$ = cheerio.load(body); // parse body html into cheerio
let links = $('a'); // get all the links in the body
$(links).each( (i, link) => {
let linkText = $(link).text();
let linkHref = $(link).attr('href');
// check if the link is dead
axios.get(linkHref)
.then( (response) => {
if (response.status != 200) {
results.push(linkHref);
}
})
.catch( (error) => {
results.push(linkHref);
});
})
return results; // this returns an empty array instead of a populated array
}
我知道axios.get()
是一个异步函数,但是我不确定如何在返回填充数组{{1}之前等待each
循环中的每个GET请求完成运行}。
编辑:这与Using async/await with a forEach loop不同,因为results
没有$(links)
函数。
编辑:我尝试过:
.forEach
但是它现在给我这个错误:
const reqs = $(links).map( async (i, link) => {
let linkText = $(link).text();
let linkHref = $(link).attr('href');
// check if the link is dead
axios.get(linkHref)
.then( (response) => {
if (response.status != 200) {
results.push(linkHref);
}
})
.catch( (error) => {
results.push(linkHref);
});
return axios.get(linkHref)
})
await Promise.all(reqs); // ERROR
return results;
编辑:我想通了。这是我的代码:
(node:77480) UnhandledPromiseRejectionWarning: TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))