Bra*_*roy 5 javascript fetch promise es6-promise
我写了一段代码片段,从Foursquare API中获取一些JSON.从这个JSON,我得到了场地的ID.然后,通过发出fetch()对每个ID 的请求,并将这些请求映射到数组中,可以使用这些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')
}
Run Code Online (Sandbox Code Playgroud)
当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
Run Code Online (Sandbox Code Playgroud)
输入then()Promise.all()后我不明白为什么,因为response从来没有ok(没有ok登录控制台).另外,我不明白为什么块中console.log()的s catch()不会被执行,或者为什么它们是空的.我没有在控制台中看到任何捕获的错误信息,但仍然getBackupData调用该函数.最后,目前还不清楚为什么控制台中的最后一条消息表明错误未被捕获,因为我预计reject()会Promise.all()失败.
如何巧妙地捕获任何错误(包括那些通常不会被错误捕获的错误catch(),例如429错误)并getBackupData在发生错误时调用?
您的问题是相关的:即,必须编辑 Promise 链return。如果你不做returnPromise,你就断开了调用者的任何Promise#catch处理,你的Promise/then代码中的任何错误都会导致未处理的promise拒绝错误,比如你得到的:
未捕获(承诺)获取场地详细信息时出错
这个未捕获的承诺拒绝出现在处理以下解析的代码中fetch:
if (response.ok) {
console.log('ok')
return response.json()
} else {
Promise.reject('Error when getting venue details') // <----
}
Run Code Online (Sandbox Code Playgroud)
由于此代码用于构造数组venuePromises,因此其return值将填充venuePromises. 如果响应正常,该数组元素将具有来自 的响应 JSON return response.json()。如果响应失败,则不会return执行任何语句,因此数组元素的值为undefined。因此,venuePromises看起来像这样:
[
{ /** some object for successful response */ },
undefined,
{ /** some other object */ },
...
]
Run Code Online (Sandbox Code Playgroud)
因此,当您的成功处理程序访问此数组时Promise.all,您会收到 TypeError,因为您希望 的所有元素都venuePromises有效。此 TypeError 被 的处理程序捕获Promise.all(.catch这就是记录它的原因,并且您会在日志中收到“备份”文本)。
return要修复,您需要Promise.reject以及. 请注意,在某些情况下是隐式的,但我发现显式的更好,特别是当语句跨越多行时。由于您要返回该语句,因此您可以将其和卸载给调用者,从而减少一层嵌套,并减少一个重复处理程序。Promise.allreturnPromise.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')
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1266 次 |
| 最近记录: |