簡體   English   中英

如何在不破壞Promise鏈的情況下處理Bluebird中的拒絕?

[英]How to handle rejections in Bluebird without breaking a Promise chain?

假設我正在構建一個典型的RSS閱讀器。 我正在解析幾個feed並將所有劇集寫入DB:

const processEpisode = (episode)=>
  fetchMetadata(episode)
  .then(parseMetadata)
  .then(writeToDb)

const processFeed = (feed)=>
  fetchEpisodes(feed) // returns [Episode]
  .map(processEpisode,  { concurrency: 3 })

// main
getFeeds() // returns [Feed]
.map(processFeed, { concurrency: 3 })
.catch(err=> console.log(err))
  1. 我們得到了所有的飼料
  2. 對於每個Feed,發出processFeed()
  3. 對於每一集,從processFeed()發出processEpisode() processFeed()

但是,如果針對某些Feed的某些劇集的fetchMetadata(episode)引發拒絕,則所有鏈都會被破壞並立即進入全局.catch(err=> console.log(err))

在正常情況下,我們需要對未經處理的劇集做一些事情,但最少應該正常處理。 一種解決方案是將processEpisode()包裝在外部Promise中並就地處理。

const processEpisode = (episode)=>
  new Promise((resolve, reject)=> {
    fetchMetadata(episode)
    .then(parseMetadata)
    .then(writeToDb)
    .then((result)=> resolve(result))
    .catch((err)=> {
      // something bad happened
      // process and error, but resolve a fullfilled Promise!
      resolve(true)
    })
  })

但是,我認為這是一個明顯的反模式。 如果在processEpisode()之后在更高級別的Promise鏈中有另一個元素,它將失敗'因為processEpisode將解析true而不是真實結果。

有沒有一種優雅的方法來解決這些問題? 我一直在尋找藍鳥的finally聲明,但我不確定這是最好的方式。

謝謝!

只需將一個.catch()處理程序直接放在processFeed()這樣就可以在本地處理拒絕並將其轉換為已解決的promise,這將允許其他所有內容繼續:

// main
getFeeds() // returns [Feed]
.map(function(item, index, length) {
    return processFeed(item, index, length).catch(function(reason) {
       // do whatever you want to here, this will "handle" the rejection
       //   and turn it into a resolved promise
       // whatever you return here will become the resolved value
    });
}, { concurrency: 3 })
.catch(err=> console.log(err))

注意:您不需要額外的包裝承諾。 添加.catch()處理程序,並從返回正常值.catch()處理程序將打開拒絕承諾為解決承諾作為拒絕被認為是“處理”在這一點上。 無論從.catch()處理程序返回什么值, .catch()成為父承諾的已解析值。

.catch()處理程序只會在拒絕承諾或拋出時拒絕承諾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM