【问题标题】:get response.status in .then in Java Script在 .then 中获取 response.status 在 Javascript
【发布时间】:2020-09-17 23:43:39
【问题描述】:

我尝试检查我的请求的状态是否为 200(OK),但我不知道如何一起做这些事情,因为第一个和第二个 .then 不是“彼此相似”:

function f(path) {
    await fetch(path)
            .then(response => {
                // console.log(response.status);
                if (response.status != 200) {
                    throw response.status;
                } else {
                    // do something
                }
            })
            .then(response => response.json())
            .then(...method for the response.json()...)
            .catch(error => {
                // print some error message
            }
}
  • 然后第二个失败并返回错误。

我扔的时候有问题。

它将错误打印到控制台(当我通过将路径更改为错误路径进行检查并且我想看看我是否处理错误时)。

我能做什么?

【问题讨论】:

  • 请添加一个minimal reproducible example(至少包括抛出的错误,并根据错误响应的内容)显示实际问题
  • 您需要在第一个then 中返回response,以便第二个then 能够使用它

标签: javascript json fetch fetch-api


【解决方案1】:

您在第一个履行处理程序(then 回调)中正确检查了它,尽管我只使用!response.ok。您通常不需要后续处理程序中的状态。

但是您的第一个履行处理程序的问题是它没有返回任何内容,因此后续履行处理程序只能看到undefined。相反,从json()返回承诺:

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json();
        })
        .then(data => {
            // ...use the data here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

请注意,您不能在传统函数中使用await,只能在async 函数中使用。但如果您使用.then.catch,则不需要它。我已经在上面删除了。

如果出于某种原因您想要后续履行处理程序中的状态,则必须从第一个履行处理程序中返回它。例如:

function f(path) {
    fetch(path)
        .then(response => {
            if (!response.ok) {
                // Note: Strongly recommend using Error for exceptions/rejections
                throw new Error("HTTP error " + response.status);
            }
            return response.json().then(data => ({status: response.status, data}));
        })
        .then(({status, data}) => {
            // ...use `status` and `data` here...
        })
        .catch(error => {
            // ...show/handle error here...
        });
}

其中,我在json() 的承诺上使用了嵌套的履行处理程序,然后返回了一个带有statusdata 的对象。

【讨论】:

    【解决方案2】:

    您需要在then 链中返回,乍一看似乎太多了。看看下面的例子...

    fetch(path)
      .then(r => r.ok ? r.json() : Promise.reject('oops')) // .statusText, etc
      .then(r => {
        // [...]
      })
      .catch(e => console.error(e)); // oops
    

    【讨论】:

      【解决方案3】:

      a) 我认为您不需要 await 关键字,因为您使用的是 .then() 链接。

      b) 你必须从第一个 then 返回一些东西,以便在下一个 .then() 中得到它

      function f(path) {
      await fetch(path)
              .then(response => {
                  // console.log(response.status);
                  if (response.status != 200) {
                      throw response.status;
                  } else {
                      // do something
                       // After doing what you need return the response
                      return response
                  }
              })
              .then(response => response.json())
              .then(...method for the response.json()...)
              .catch(error => {
                // print some error message
                }
      }

      【讨论】:

        【解决方案4】:

        实际上,尚不清楚您的函数必须做什么。但我认为你的挣扎来自于没有完全理解承诺链是如何工作的。为此,我建议您熟悉this 文章,它对我有很大帮助:)

        回到你的功能。优雅的解决方案是添加简单的“tap”功能,它允许您使用当前响应做一些事情,但它仍然会进一步将响应传递给其他 .then 链。

        点击功能如下:

        const tap = (callback) => (value) => (callback(value), value);
        

        最后如何使用它:

        function f(path) {
          fetch(path)
            .then(
              tap((response) => {
                if (response.status !== 200) throw new Error(response.status);
              })
            )
            .then((response) => {
              // do other stuff
            })
            .catch((error) => console.error(error));
        }
        

        【讨论】:

          【解决方案5】:

          支持fetch但不支持async/await的浏览器数量现在非常少,因此您最好先使用这种更简单的语法,然后再为旧版浏览器与您的fetch 的垫片。

          你的函数变成:

          try {
              const response = await fetch(path);
          
              // console.log(response.status);
              if (response.status != 200) {
                  throw response.status;
              } else {
                  // do something
              }
          
              const parsed =  await response.json();
          
              // do something with parsed
          }
          catch(error) {
              // print some error message
          }
          

          这种新语法使处理不同 then 操作中的错误变得更加容易:

          const response = await fetch(path);
          
          // console.log(response.status);
          if (response.status != 200) {
              throw response.status;
          } else {
              // do something
          }
          
          let parsed; // Will hold the parsed JSON
          try {    
              parsed =  await response.json();
          }
          catch(error) {
              // Deal with parsing errors
          }
          
          try {
              // do something with parsed
          }
          catch(error) {
              // Deal with errors using the parsed result
          }
          

          【讨论】:

            猜你喜欢
            • 2017-07-08
            • 2018-04-26
            • 2020-12-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-09
            • 1970-01-01
            • 2019-11-22
            相关资源
            最近更新 更多