【问题标题】:Handling errors in Promise处理 Promise 中的错误
【发布时间】:2019-02-17 08:56:00
【问题描述】:

我正在用 JavaScript 编写天气应用程序,你可以猜到有很多 API 请求。所以在这里我向 API 发出请求,然后它将返回我的城市图像。城市来自用户输入。

async getCityImage(city) {
    console.log(city, 'getCityImage');
    await fetch(`https://api.teleport.org/api/urban_areas/slug:${city}/images/`)
      .then(res => res.json())
      .then((res) => {
        this.imageUrl = res.photos[0].image.mobile;
      });
  }
}

问题是用户输入可能不合适,当然 API 会返回这样的错误

> GET https://api.teleport.org/api/urban_areas/slug:munchen/images/ 404

(未找到)

For example there are some cities which names are separated by hyphen 

坎萨斯城、危地马拉城等......

所以我想处理错误,以便错误不会影响 UI,但是发出另一个这样的请求,然后返回答案`

GET https://api.teleport.org/api/urban_areas/slug:${city}-city/images/

当时我试图通过嵌套请求来实现它,但它不起作用

【问题讨论】:

  • 请告诉我们您尝试了什么

标签: javascript error-handling promise async-await fetch


【解决方案1】:

你可以使用这样的东西

async getCityImage(city) {
    console.log(city, 'getCityImage');
    await fetch(`https://api.teleport.org/api/urban_areas/slug:${city}/images/`)
      .then(res => res.json())
      .then((res) => {
        this.imageUrl = res.photos[0].image.mobile;
      })
      .catch((e) => { //do something with error});
  }
}

【讨论】:

  • 你可以在 await 中使用.then 吗?
  • 我已经尝试过了,但是在 catch 里面,当我获取一些 API 时,我不能等待它。它给了我一个错误`[等待是保留字]。跟then也是一样的
  • await is reserved word 表示您错过了关键字async
  • 那么你把它放在哪里了?在then 内?
  • @tallpaulk 是的,你可以,但你不应该(specific error handling purposes 除外)
【解决方案2】:

你可以像这样使用 try catch 语句:

async getCityImage(city) {
  let res;
  try {
    res = await fetch(`https://api.teleport.org/api/urban_areas/slug:${city}/images/`); 
    return res.photos[0].image.mobile;
  } catch(e) {
    // here you can do something when the request fails
    res = await trySomethingElse();
    return res
  }
}

【讨论】:

    【解决方案3】:

    这是我的解决方案,可能不是最好的,但在这种情况下它可以帮助我。

    getCityImage(city, hyphen) {
        console.log(city, 'getCityImage');
        return fetch(`https://api.teleport.org/api/urban_areas/slug:${city}/images/`)
          .then(res => res.json())
          .then((res) => {
            if (res.status === 404)
              return fetch(`https://api.teleport.org/api/urban_areas/slug:${city}-city/images/`)
                .then(res => res.json());
            else
              return res;
          })
          .then((res) => {
            this.imageUrl = res.photos[0].image.mobile;
          })
          .catch((err) => {
            console.log(err, 'erroroooooooorr');
          });
    }
    

    【讨论】:

    • 如果此解决方案不起作用,您应该 put it in your question。还是现在?
    • 它正在工作。我现在应该关闭答案吗?如果是,我应该怎么做?
    • 实际上我怀疑它是否有效,您需要交换 .then(res => res.json()).then((res) => { if (res.status === 404) { … - 解析的 JSON 不会有 status 属性。还要避免Promise constructor antipattern!
    • {status: 404, message: "Not Found. You have requested this URI [/api/publi…ex("slug\:[0-9a-z-]+"):urban_area_id>/salaries/ ?"} "response000" 这就是答案。实际上它有一个status
    • 完成。您可能希望将现在使用两次的 fetch(…).then(res => res.json()) 提取到辅助函数中。
    【解决方案4】:

    你可以这样做 -

    本机提取 API - 已更新

    (async () => {
    
        async function getCityImage(city) {
            let response = await fetch(`https://api.teleport.org/api/urban_areas/slug:${city}/images/`);
            if (response && response.status && response.status === 200) {
                const json = await response.json();
                return json.photos[0].image.mobile;
            } else {
                throw Error(`got error, error code - ${response.status}`);
            }
        }
    
        try {
            console.log(await getCityImage("london"));
            console.log(await getCityImage(null));
        } catch (error) {
            console.error(error);
        }
    
    })();

    【讨论】:

    • 您是否使用fetch node module 从网址获取数据?如果您已经拥有它,您也可以分享该代码吗?
    • 检查更新的答案。这将捕获所有网络错误。
    • 没有 async/await 它甚至不会返回相应城市的图像
    • @planet_hunter 如果您使用的是async/await,则根本不需要使用then。不要混合它们。顺便说一句,在async function 中你可以只使用throwreturn,你不需要使用Promise.resolvePromise.reject
    猜你喜欢
    • 2019-01-05
    • 2016-04-20
    • 2016-06-08
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    相关资源
    最近更新 更多