【发布时间】:2019-01-30 23:58:09
【问题描述】:
这段代码有问题:
fetch('/example.json')
.then(response => Promise.all([response, response.json()])) // This line throws unhandled exception: SyntaxError: Unexpected token < in JSON at position 0
.then(([response, json]) => {
if (!response.ok) {
throw new Error(JSON.stringify(json));
}
return json;
})
.catch(exception => {
const error = new Map([
[TypeError, ["There was a problem fetching the response."]],
[SyntaxError, ["There was a problem parsing the response."]],
[Error, JSON.parse(exception.message)]
]).get(exception.constructor);
return { error };
})
它在大多数情况下都可以正常工作,但是当服务器的响应为 200 OK 时它会失败,但实际内容是 HTML。我知道这是服务器上的错误,但我只想让我的客户正确处理它。也就是说,它应该使用最终的 catch 来捕获 response.json() 异常。
我做错了什么?
【问题讨论】:
-
调用
JSON.parse(exception.message)而不考虑实际的exception看起来是个坏主意。 -
究竟是什么让您认为您的最终
catch没有处理异常? -
进一步观察,catch 也确实执行了。但是,打开 devtools 的 Chrome 会在 response.json() 上停止执行(恢复执行后,它会执行 catch)。在捕获发生之前停止执行是正常的 devtools 行为吗?
-
我认为是的,它停在引发异常/拒绝承诺的行上,而不仅仅是在您可能设置断点的
catch上。 -
这段代码太奇怪了,以至于它会很麻烦。
Promise.all()在那个位置是不合适的,很可能是这里所有问题的原因。Promise.all()的第一个参数是从请求中解析的 Promise,因此什么都不做,第二个是通常预期的操作,它解析(在这种情况下)解析为 JSON。if(!response.ok)条件代码应放在第一个.then()内,因为这是处理响应的适当时间。那么“良好”条件下的返回语句应该是return response.json()。
标签: javascript promise fetch