Предположим, что я строю типичный RSS-ридер. Я разбор несколько каналов и записать все свои эпизоды к БД:Как обращаться с отклонениями в Bluebird, не нарушая цепочку обещаний?
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))
- Мы получаем все каналы
- Для каждого кормления испускают
processFeed()
- Для каждого эпизода выделяет
processEpisode()
изprocessFeed()
Однако, если fetchMetadata(episode)
для некоторого эпизода для некоторого фида выбрасывает отказ, все цепочка разбивается и сразу попадает в глобальную .catch(err=> console.log(err))
.
В нормальной ситуации нам нужно что-то сделать с необработанным эпизодом, но наименьшее должно обрабатываться нормально. Одним из решений является обертка processEpisode()
в наружном обещании и ручке на месте.
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()
есть еще один элемент в цепочке обещаний более высокого уровня, он не сработает, потому что processEpisode
решит true
вместо реального результата.
Есть ли элегантный способ решения таких проблем? Я просматриваю заявление finally
в Bluebird, но я не уверен, что это лучший способ.
Спасибо!
Пробовал это прямо перед вашим комментарием, и это сработало :) Спасибо за подтверждение. Отметив это как решение. – f1nn