2016-09-28 85 views
1

我正在使用一個抓取函數從數組中列出的一堆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選擇器是錯誤的),地圖函數/請求繼續做是工作,它返回錯誤(或空值)作爲一個值附加到最終數組對象中的url。

+0

所有的URL從API獲取。我正在做這樣的事情'return getmyurls()。then((rows)=> {const urls = rows; return getNbShares(urls).then((nbshares)etc ...' –

回答

1

我認爲你只是想在處理函數中儘早處理一下;我認爲你可以避免有兩個單獨的映射操作;看評論:

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