【发布时间】:2019-01-21 14:26:23
【问题描述】:
我编写了一段从 Foursquare API 获取 JSON 的 sn-p 代码。从这个 JSON 中,我得到了场地的 ID。然后,通过为每个 ID 发出 fetch() 请求并将这些请求映射到数组中,这些 ID 用于从这些特定场所获取更多详细信息。然后将该数组传递给Promise.all()。当 API 可用时,一切正常,但我无法理解的是错误捕获。
fetch(`https://api.foursquare.com/v2/venues/search?${params}`)
.then(response => response.json())
.then(data => {
const venueIds = data.response.venues.map(venue => venue.id)
const venuePromises = venueIds.map(venueId => {
fetch(`https://api.foursquare.com/v2/venues/${venueId}?${otherParams}`)
.then(response => {
// Must check for response.ok, because
// catch() does not catch 429
if (response.ok) {
console.log('ok')
return response.json()
} else {
Promise.reject('Error when getting venue details')
}
})
})
Promise.all(venuePromises).then(data => {
const venues = data.map(entry => entry.response.venue) // Error for this line
this.parseFsqData(venues)
}).catch((e) => {console.log(e); getBackupData()})
}).catch((e) => {console.log(e); getBackupData()})
function getBackupData() {
console.log('backup')
}
当 API 不可用时,我会收到以下控制台错误(以及更多相同的错误):
TypeError: Cannot read property 'response' of undefined
at MapsApp.js:97
at Array.map (<anonymous>)
at MapsApp.js:97
backup
api.foursquare.com/v2/venues/4b7efa2ef964a520c90d30e3?client_id=ANDGBLDVCRISN1JNRWNLLTDNGTBNB2I4SZT4ZQYKPTY3PDNP&client_secret=QNVYZRG0JYJR3G45SP3RTOTQK0SLQSNTDCYXOBWUUYCGKPJX&v=20180323:1 Failed to load resource: the server responded with a status of 429 ()
Uncaught (in promise) Error when getting venue details
我不明白为什么在输入 Promise.all() 之后then(),因为response 永远不是ok(控制台中没有ok 登录)。另外,我不明白为什么catch() 块中的console.log() 没有被执行,或者为什么它们是空的。我在控制台中没有看到任何捕获的错误信息,但仍然调用了 getBackupData 函数。最后,不清楚为什么控制台中的最后一条消息表明错误是未捕获,因为我预计reject() 会使Promise.all() 失败。
如何巧妙地捕捉到任何错误(包括那些通常不会被catch() 捕捉到的错误,例如429 错误)并在出现任何错误时调用getBackupData?
【问题讨论】:
-
你不会返回那个
Promise.reject('Error when getting venue details'),所以venuePromises的索引值是undefined,而不是一个被拒绝的Promise。 -
@tehhowch 你得到了很好的答案.....作为评论。
-
@escapesequence 感觉像是一个“由错字引起”的问题。我不回答这些。现在我查看了更多代码,但还有更多遗漏的
return语句,所以是时候写一个了 -
@tehhowch 够公平
标签: javascript promise fetch es6-promise