如何等待直到每个循环中的异步调用完成后再继续

时间:2019-08-06 20:11:38

标签: javascript node.js async-await axios

我正在使用 cheerio axios从网页上获取所有链接,并通过axios发出 GET 请求并检查每个链接是否为未损坏的链接( 状态码为200 )。

然后,我想将每个断开的链接 URL 放入一个数组中。 我无法用asyncawait来解决这个问题。

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))

0 个答案:

没有答案