返回一个带有promise的数组对象值

Returning error as an array object value with promise

本文关键字:promise 数组 对象 一个 返回      更新时间:2023-09-26

我使用抓取函数从数组内列出的一堆urls中获取一些数据。下面是函数:

function getNbShares(urls) {
    return Promise.map(urls, request).map((htmlOnePage, index) => {
        const $ = cheerio.load(htmlOnePage),
            share = $('.nb-shares').html();
        return {
            url: urls[index],
            value: share
        };
    }).catch(function (urls, err) {
        return {
            url: urls[index],
            value: err
        };
    });
}

它工作正常,但是错误处理不是。我想要的是,当我有一个错误(无论是因为页面不加载或如果DOM选择器是错误的)地图函数/请求继续做的工作,它返回我的错误(或null)作为一个值附加到url在最后的数组对象。

我想你只是想在映射函数中更早地处理这个问题;我认为你可以避免两个独立的映射操作;看到评论:

function getNbShares(urls) {
    return Promise.map(
        urls,
        url => request(url)
                .then(htmlOnePage => {                   // Success, so we parse
                    const $ = cheerio.load(htmlOnePage), // the result and return
                        value = $('.nb-shares').html();  // it as an object with
                    return { url, value };               // `url` and `value` props
                })
                .catch(error => ({url, error}))          // Error, so we return an
                                                         // object with `url` and
                                                         // `error` props
        }
    );
}

(我假设你正在使用ES2015+,因为你正在使用箭头函数)

我可能会选择将部分因素排除:

function getNbSharesFromHTML(html) {
    const $ = cheerio.load(html);
    return $('.nb-shares').html();
}
function getNbShares(urls) {
    return Promise.map(
        urls,
        url => request(url)
                .then(htmlOnePage => ({url, value: getNbSharesFromHTML(htmlOnePage)))
                .catch(error => ({url, error}))
        }
    );
}

可能更小:

function getNbSharesFromHTML(html) {
    const $ = cheerio.load(html);
    return $('.nb-shares').html();
}
function getNbSharesFromURL(url) {
    return request(url)
            .then(htmlOnePage => ({url, value: getNbSharesFromHTML(htmlOnePage)))
            .catch(error => ({url, error}));
}
function getNbShares(urls) {
    return Promise.map(urls, getNbSharesFromURL);
}