gpt4 book ai didi

javascript - Promise.all() 和捕获错误

转载 作者:搜寻专家 更新时间:2023-11-01 04:12:39 24 4
gpt4 key购买 nike

我写了一段代码,从 Foursquare API 获取一些 JSON。从这个 JSON 中,我得到了 field 的 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

我不明白为什么 then() 在输入 Promise.all() 之后,因为 response 永远不会 ok (有没有 ok 登录控制台)。另外,我不明白为什么 catch() block 中的 console.log() 没有执行,或者为什么它们是空的。我在控制台中没有看到任何捕获到的错误信息,但仍然调用了 getBackupData 函数。最后,不清楚为什么控制台中的最后一条消息指示错误未被捕获,正如我预期的那样 reject() 使 Promise.all() 失败。

我如何巧妙地捕获任何错误(包括那些通常不会被 catch() 捕获的错误,例如 429 错误)并在发生任何错误时调用 getBackupData

最佳答案

您的问题是相关的:即,Promise 链必须被 returned。如果您不返回 Promise,您将断开任何调用者的Promise#catch 处理,并且您的Promise/then 代码中的任何错误都会导致未处理的 promise 拒绝错误,比如你得到了什么:

Uncaught (in promise) Error when getting venue details

这个未捕获的 promise 拒绝出现在处理 fetch 解析的代码中:

if (response.ok) {
console.log('ok')
return response.json()
} else {
Promise.reject('Error when getting venue details') // <----
}

由于此代码用于构造您的 venuePromises 数组,因此其 return 值将填充 venuePromises。如果响应正常,该数组元素将具有来自 return response.json() 的响应 JSON。如果响应失败,则不会执行任何return 语句,因此数组元素的值为undefined。因此,venuePromises 看起来像这样:

[
{ /** some object for successful response */ },
undefined,
{ /** some other object */ },
...
]

因此,当您的 Promise.all 的成功处理程序访问此数组时,您会收到 TypeError,因为您希望 venuePromises 的所有元素都有效。此 TypeError 被 Promise.all.catch 处理程序捕获(这就是它被记录的原因,并且您会在日志中收到“备份”文本)。

要修复,您需要返回 Promise.reject还有 Promise.all。请注意,有一些情况 implicit return ,但我发现明确表示更好,尤其是当语句跨越多行时。由于您要返回 Promise.all 语句,您可以将其 .then.catch 卸载给调用者,从而减少一个嵌套级别,并且减少了一个重复的 .catch 处理程序。

fetch(`https://api.foursquare.com/v2/venues/search?${params}`)
.then(response => response.json())
.then(jsonData => {
const venueIds = jsonData.response.venues.map(venue => venue.id);
const venuePromises = venueIds.map(venueId => {
let link = `https://api.foursquare.com/v2/venues/${venueId}?${otherParams}`;
return fetch(link).then(response => {
// Must check for response.ok, because catch() does not catch 429
if (response.ok) {
console.log('ok');
return response.json();
} else {
console.log(`FAILED: ${link}`);
// Return a Promise
return Promise.reject(`Error when getting venue details for '${venueId}'`);
}
});
});

return Promise.all(venuePromises);
})
.then(venueData => {
const venues = venueData.map(entry => entry.response.venue);
this.parseFsqData(venues);
})
.catch(e => {console.log(e); getBackupData()});

function getBackupData() {
console.log('backup')
}

关于javascript - Promise.all() 和捕获错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51846348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com