处理嵌套承诺中的所有承诺拒绝?
我正在使用Promise.race,所以我可以暂时out fetch通话。在不存在的API端点的测试期间,我会遇到“未手持的承诺拒绝”错误。该代码应该构架。log曾经发生任何故障。我在哪里不处理承诺拒绝?仅供参考,主要功能是功能检索
window.path = "http://localhost:3000/records";
function isPrimary(color) {
let colorIsPrimary = false;
(color.startsWith("red") || color.startsWith("blue") || color.startsWith("yellow")) ? colorIsPrimary = true : null;
return colorIsPrimary;
}
function transformData(records,page) {
const transformedData = {
"ids" : [],
"open": [],
"closedPrimaryCount": 0,
"previousPage": null,
"nextPage": null
}
let closedPrimaryCount = 0;
records.forEach((record, index) => {
if (index < 10) {
transformedData.ids.push(record.id);
record["isPrimary"] = false;
isPrimary(record.color) ? record.isPrimary = true : null;
record.disposition == "open" ? transformedData.open.push(record) : null;
if (record.disposition == "closed") {
isPrimary(record.color) ? closedPrimaryCount++ : null;
}
}
})
transformedData.closedPrimaryCount = closedPrimaryCount;
let previousPage = null;
page > 1 ? previousPage = page - 1 : null;
transformedData.previousPage = previousPage;
let nextPage = null;
records.length > 10 ? nextPage = page + 1 : null;
transformedData.nextPage = nextPage;
return transformedData;
}
function promiseTimeout(promise, ms) {
let timeout = new Promise((resolve, reject) => {
let timeoutID = setTimeout(() => {
clearTimeout(timeoutID);
reject("fetch failed - timeout");
}, ms)
})
return Promise.race([promise, timeout]);
}
function doFetch(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => {
if (!response.ok) {
reject(new Error("fetch failed - non 200"));
}
response.json()
.then((records) => {
resolve(records);
})
.catch((error) => {
reject(new Error("fetch failed - error from response.json"));
})
})
.catch((error) => {
reject(new Error("fetch failed - error from fetch"));
})
})
}
function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"], thetest = false, windowPath = window.path} = {}) {
return new Promise((resolve,reject)=>{
!thetest ? windowPath = "http://localhost:3000/records" : null;
// limit set to 11 so we can determine nextPage
const limit = "11";
const offset = "" + ((page * 10) - 10);
let colorArgs = "";
colors.forEach((color, index) => {
colorArgs = colorArgs + "&color[]=" + color;
});
const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
const requestURL = new URI(windowPath);
requestURL.query(requestQuery);
const promiseRace = promiseTimeout(doFetch(requestURL.toString()), 4000);
promiseRace.then((records) => {
const transformedData = transformData(records, page);
resolve(transformedData);
})
promiseRace.catch((error) => {
console.log(error);
})
});
};
export default retrieve;
I'm using Promise.race so I can time out the fetch call. During a test to an API endpoint that doesn't exist, I'm getting an "Unhandled promise rejection" error. The code is supposed to console.log once upon any failure. Where am I not handling the promise rejection? FYI the main function is function Retrieve
window.path = "http://localhost:3000/records";
function isPrimary(color) {
let colorIsPrimary = false;
(color.startsWith("red") || color.startsWith("blue") || color.startsWith("yellow")) ? colorIsPrimary = true : null;
return colorIsPrimary;
}
function transformData(records,page) {
const transformedData = {
"ids" : [],
"open": [],
"closedPrimaryCount": 0,
"previousPage": null,
"nextPage": null
}
let closedPrimaryCount = 0;
records.forEach((record, index) => {
if (index < 10) {
transformedData.ids.push(record.id);
record["isPrimary"] = false;
isPrimary(record.color) ? record.isPrimary = true : null;
record.disposition == "open" ? transformedData.open.push(record) : null;
if (record.disposition == "closed") {
isPrimary(record.color) ? closedPrimaryCount++ : null;
}
}
})
transformedData.closedPrimaryCount = closedPrimaryCount;
let previousPage = null;
page > 1 ? previousPage = page - 1 : null;
transformedData.previousPage = previousPage;
let nextPage = null;
records.length > 10 ? nextPage = page + 1 : null;
transformedData.nextPage = nextPage;
return transformedData;
}
function promiseTimeout(promise, ms) {
let timeout = new Promise((resolve, reject) => {
let timeoutID = setTimeout(() => {
clearTimeout(timeoutID);
reject("fetch failed - timeout");
}, ms)
})
return Promise.race([promise, timeout]);
}
function doFetch(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => {
if (!response.ok) {
reject(new Error("fetch failed - non 200"));
}
response.json()
.then((records) => {
resolve(records);
})
.catch((error) => {
reject(new Error("fetch failed - error from response.json"));
})
})
.catch((error) => {
reject(new Error("fetch failed - error from fetch"));
})
})
}
function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"], thetest = false, windowPath = window.path} = {}) {
return new Promise((resolve,reject)=>{
!thetest ? windowPath = "http://localhost:3000/records" : null;
// limit set to 11 so we can determine nextPage
const limit = "11";
const offset = "" + ((page * 10) - 10);
let colorArgs = "";
colors.forEach((color, index) => {
colorArgs = colorArgs + "&color[]=" + color;
});
const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
const requestURL = new URI(windowPath);
requestURL.query(requestQuery);
const promiseRace = promiseTimeout(doFetch(requestURL.toString()), 4000);
promiseRace.then((records) => {
const transformedData = transformData(records, page);
resolve(transformedData);
})
promiseRace.catch((error) => {
console.log(error);
})
});
};
export default retrieve;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在Ggorlen的出色建议之后,我重构了这项更清洁(和测试)的代码:
After ggorlen's excellent advice, I refactored to this much cleaner (and test-passing) code: