使用 Promise.allSettled 捕获被拒绝承诺的请求响应代码
Capture request response code of rejected promises with Promise.allSettled
我正在使用 Promise.allSettled
调用一组 URL,我需要捕获被拒绝承诺的请求的响应代码。使用 Promise.allSettled
提供的 result.reason
的值不足以准确评估拒绝承诺的原因。我需要请求响应代码(400、500、429 等)。
到目前为止我有以下内容:
var response = await Promise.allSettled(urls.map(url => fetch(url)))
.then(results => {
var data = [];
results.forEach((result, num) => {
var item = {
'req_url': urls[num],
'result': result.status,
'result_details': result
};
data.push(item);
});
return data;
});
我如何捕获被拒绝承诺的请求的响应代码并将其作为 属性 添加到返回的数组中?返回的数组应该看起来像这样:
[{
'req_url': 'https://myurl.xyz/a',
'req_status_code': 400,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:876'
}
},
{
'req_url': 'https://myurl.xyz/b',
'req_status_code': 419,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:890'
}
},
{
'req_url': 'https://myurl.xyz/c',
'req_status_code': 429,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:925'
}
}]
有什么想法吗?
fetch
不会拒绝它对 HTTP 失败的承诺,只有 network 失败。 (在我看来 API 脚枪,I wrote up 几年前在我贫血的旧博客上。)我通常通过将 fetch
包装在 做的事情中来解决这个问题 拒绝 HTTP 失败。您也可以这样做,并在拒绝原因中提供失败状态。 (但您不必这样做,请参阅下文。)
class FetchError extends Error {
constructor(status) {
super(`HTTP error ${status}`);
this.status = status;
}
}
async function goFetch(url, init) {
const response = await fetch(url, init);
if (!response.ok) {
// HTTP error
throw new FetchError(response.status);
}
return response;
}
然后你可以将一个 async
函数传递给 map
以在本地处理错误,并使用 Promise.all
(只是因为在一个地方做这一切比在两个地方做更简单Promise.allSettled
):
const results = await Promise.all(urls.map(async url => {
try {
const response = await goFetch(url);
// ...you might read the response body here via `text()` or `json()`, etc...
return {
req_url: url,
result: "fulfilled",
result_details: /*...you might use the response body here...*/,
};
} catch (error) {
return {
req_url: url,
result: "rejected",
result_status: error.status, // Will be `undefined` if not an HTTP error
message: error.message,
};
}
}));
或者你可以在没有 fetch
包装器的情况下做到这一点:
const results = await Promise.all(urls.map(async url => {
try {
const response = await fetch(url);
if (!response.ok) {
// Local throw; if it weren't, I'd use Error or a subclass
throw {status: response.status, message: `HTTP error ${response.status}`};
}
// ...you might read the response body here via `text()` or `json()`, etc...
return {
req_url: url,
result: "fulfilled",
result_details: /*...you might use the response body here...*/,
};
} catch (error) {
return {
req_url: url,
result: "rejected",
result_status: error.status, // Will be `undefined` if not an HTTP error
message: error.message,
};
}
}));
我正在使用 Promise.allSettled
调用一组 URL,我需要捕获被拒绝承诺的请求的响应代码。使用 Promise.allSettled
提供的 result.reason
的值不足以准确评估拒绝承诺的原因。我需要请求响应代码(400、500、429 等)。
到目前为止我有以下内容:
var response = await Promise.allSettled(urls.map(url => fetch(url)))
.then(results => {
var data = [];
results.forEach((result, num) => {
var item = {
'req_url': urls[num],
'result': result.status,
'result_details': result
};
data.push(item);
});
return data;
});
我如何捕获被拒绝承诺的请求的响应代码并将其作为 属性 添加到返回的数组中?返回的数组应该看起来像这样:
[{
'req_url': 'https://myurl.xyz/a',
'req_status_code': 400,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:876'
}
},
{
'req_url': 'https://myurl.xyz/b',
'req_status_code': 419,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:890'
}
},
{
'req_url': 'https://myurl.xyz/c',
'req_status_code': 429,
'result': 'rejected',
'result_details': {
'status': 'rejected',
'message': 'TypeError: Failed to fetch at <anonymous>:1:925'
}
}]
有什么想法吗?
fetch
不会拒绝它对 HTTP 失败的承诺,只有 network 失败。 (在我看来 API 脚枪,I wrote up 几年前在我贫血的旧博客上。)我通常通过将 fetch
包装在 做的事情中来解决这个问题 拒绝 HTTP 失败。您也可以这样做,并在拒绝原因中提供失败状态。 (但您不必这样做,请参阅下文。)
class FetchError extends Error {
constructor(status) {
super(`HTTP error ${status}`);
this.status = status;
}
}
async function goFetch(url, init) {
const response = await fetch(url, init);
if (!response.ok) {
// HTTP error
throw new FetchError(response.status);
}
return response;
}
然后你可以将一个 async
函数传递给 map
以在本地处理错误,并使用 Promise.all
(只是因为在一个地方做这一切比在两个地方做更简单Promise.allSettled
):
const results = await Promise.all(urls.map(async url => {
try {
const response = await goFetch(url);
// ...you might read the response body here via `text()` or `json()`, etc...
return {
req_url: url,
result: "fulfilled",
result_details: /*...you might use the response body here...*/,
};
} catch (error) {
return {
req_url: url,
result: "rejected",
result_status: error.status, // Will be `undefined` if not an HTTP error
message: error.message,
};
}
}));
或者你可以在没有 fetch
包装器的情况下做到这一点:
const results = await Promise.all(urls.map(async url => {
try {
const response = await fetch(url);
if (!response.ok) {
// Local throw; if it weren't, I'd use Error or a subclass
throw {status: response.status, message: `HTTP error ${response.status}`};
}
// ...you might read the response body here via `text()` or `json()`, etc...
return {
req_url: url,
result: "fulfilled",
result_details: /*...you might use the response body here...*/,
};
} catch (error) {
return {
req_url: url,
result: "rejected",
result_status: error.status, // Will be `undefined` if not an HTTP error
message: error.message,
};
}
}));