为什么 Fetch Promise 不对错误响应进行拒绝

释放双眼,带上耳机,听听看~!

为什么 Fetch Promise 不对错误响应进行拒绝

问题

如果你一直在浏览器或现代版本的 Node.js 中使用该函数,您就会知道它会返回一个 Promise。fetch()

fetch(request).then((response) => {
 // Handle the response.
})

你还知道,如果 JavaScript 中的 promise 在解决时出现错误,则会拒绝它们。但是,由于某种不明原因,当我们收到错误响应时,返回的 Promise 永远不会被拒绝。这不仅令人困惑,而且还迫使您在进一步处理响应之前显式检查响应状态:fetch()

fetch(request).then((response) => {
 if (!response.ok) {
 throw new Error(`Server responded with ${response.statusCode}`)
 }

 return response.json()
})

好的,在你把这个行为添加到 JavaScript 怪异的列表中之前,让我向你保证它是完全正确的。你认为它是出乎意料的,仅仅是因为 fetch Promise 代表你认为它的作用。让我解释一下。

承诺

自然地,当请求返回 promise 时,我们希望其 fulfillment state 反映该请求的状态:

  • 如果请求成功,则 Promise 将解析;
  • 如果请求不成功(即失败),则 Promise 会拒绝

而这正是发生的事情!不同之处在于,您可能会从网络代码的角度误解了“成功请求”实际上是什么。

网络代码

下面是一个请求/响应事务,以稍微简化的步骤列表表示:

  1. 在您的代码中触发请求;
  2. 请求标头将发送到服务器。请记住,我说的是 HTTP 消息标头,即:
GET https://kettanaito.com HTTP/1.0
accept: text/html;charset=UTF-8
# ...the rest of the request headers, excluding the body.
  1. 请求正文开始流式传输到服务器。
  2. 请求正文完成流式处理。
  3. 服务器发送响应标头。
  4. 响应正文完成流式传输到客户端。

从网络代码的角度来看,一旦请求被成功完整地发送到服务器(在上面的列表中传递了 #3),它就是成功的。虽然这有点违反直觉,但 request 的成功与你从服务器得到的响应类型无关。

只要传出请求被成功解析并发送到 server,则视为成功。

这意味着 fetch() 函数返回的 Promise 实际上是一个请求 Promise,并且只有在请求本身失败时才会拒绝。

错误响应

请记住,错误响应并不表示请求失败。要使应用程序从服务器获取错误,它必须到达该服务器,这意味着它必须成功发送请求并返回某些内容。

这又一次是意图的混淆。作为开发人员,我们在发出请求时的目的是为该请求获得 “满意路径” 解决方案。如果我们获取 ,我们希望得到 puppies 的列表。其他任何事情都被认为是意外的,即错误。GET /puppies

但是 fetch() 不能真的假设这一点。考虑一下我们实际上期望的是 error 响应而不是 .突然之间,我们对响应的期望取决于上下文,而不是 fetch 应该关心的事情。200 OK

拒绝

尽管人们普遍认为 Promise 确实拒绝了,以下是时间:fetch()

  • 请求构造错误;
  • 网络错误(例如 DNS 查找失败、无法访问网络);
  • 请求已中止。

而这些正是你在 request Promise 的结尾应该处理的情况:.catch()

fetch(request)
 .then((response) => {
 // Handle the response.
 })
 .catch((error) => {
 // Handle request errors.
 })

等等,但这实际上很不错!如果请求成功,我们将继续在回调中处理其响应(无论它是什么),如果请求本身失败,我们可以在回调中捕获并处理该错误。.then().catch()

Fetch API 是 Web 上设计良好的 API 之一,正是像这样的细节表明了这一点。请记住,在你思考一些奇怪的事情之前,试着更深入地了解它,也许,过去的古怪会成为未来的发现。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
技术教程

Null 和 Undefined 之间的区别

2024-9-2 15:37:11

技术教程

函数思考,第二部分:高阶函数

2024-9-2 17:09:29

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索