fetch,promise and handling error

1. 基于callbackXMLHttpRequest处理http请求

a simple XMLHttpRequest example from MDN:

function reqListener(){
  console.log(this.responseText);
}
var oReq=new XMLHttpRequest();
oReq.addEventListener('load',reqListener);
oReq.open('GET','http://www.example.org/example.txt');
oReq.send();

2. 基于promisefetch处理http请求

fetch API 能够帮助我们不用记住xhr那么多的callback函数,一个基本的用法如下:

fetch('myResource.json').then(function(response) {
  return response.json();
}).then(function(parsedJson) {
  console.log('This is the parsed json', parsedJson);
})

很明显,这是一个promise chain

  • fetch返回一个valueresponse objectresolved promise;
  • response object调用Body.json()函数,返回一个新的promise,这个promiseresolve之后,返回的value值为resulting json.

一个比较复杂的应用场景:用fetch得到user信息之后,在当前页面显示其github主页的头像:

fetch('./infos/user.json')
.then(response=>response.json())
.then(user=>fetch(`https://api.github.com/users/${user.name}`))
.then(response=>response.json())
.then(githubUser => new Promise(function(resolve, reject) {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";
    document.body.append(img);
    setTimeout(() => {
      img.remove();
      resolve(githubUser);
    }, 3000);
  })
)
.then(githubUser => alert(`Finished showing ${githubUser.name}`));

时刻记住,.then会返回promise对象:

3种情况

3. Promise处理error

基本的概念梳理:

  • executor或者.then() handler里面不管主动throw error还是代码出现了runtime error,两者都是等效的。
    (因为promise自带隐形的try...catch)
  • 两者都会导致 return rejected promise, 返回的value值是error

一旦出现了error, promise rejected, 我们当然可以在.catch中处理。

3.1 rethrow error

// 执行:catch -> then
new Promise((resolve, reject) => {

  throw new Error("Whoops!");

}).catch(function(error) {

  alert("The error is handled, continue normally");

}).then(() => alert("Next successful handler runs"));

上述代码中的catch handler处理了error之后,返回一个resolved promise, valueundefined, js引擎继续执行下面这个then handler
现在让我们终于进入正题,我们怎么样在fetch请求中利用rethrow和promise处理error机制来更好地处理error呢?

class HttpError extends Error{
  constructor(response){
    super(`${response.status} for ${response.url}`);
    this.name='HttpError';
    this.response=response;
  }
}

我们定义了一个自己的Error class: HttpError, 下面我们就在自己的代码中使用它。

loadJson(url){
  return fetch(url)
  .then((response)=>{
    if (response.status == '200'){  
      response.json();
      }
    else{
      throw new HttpError(response);
    }
  });
}
//using HttpError in a case below:
function githubUser(){
  let name=prompt('Enter a name:', 'emma');
   return loadJson(`https://github.com/users/${name}`)
  .then((user)=>{
  console.log(user.name);
  return user;
  })
  .catch(error()=>{ (*)
    if(error instance of HttpError && error.response.status == '404'){
      console.log('No such user, please re-enter.');
      return githubUser();
    }else{
      throw(error); (**)
    }
  })
}

如果在(*)处的catch handler中,我们发现error不是HttpError, 那么我们就认定这个handler无法处理这个error,rethrow it (**).
在全局环境中,增加一个eventListener

window.addEventListener('unhandledrejection',()=>{});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 12,798评论 1 56
  • 一、Promise的含义 Promise在JavaScript语言中早有实现,ES6将其写进了语言标准,统一了用法...
    Alex灌汤猫阅读 4,278评论 0 2
  • # Ajax标签(空格分隔): 笔记整理---[TOC]### 从输入网址开始:- 在学习ajax之前,你应该先了...
    V8阅读 2,394评论 1 0
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 13,177评论 0 3
  • 本博客转自:「作者:若愚链接:https://zhuanlan.zhihu.com/p/22361337来源:知乎...
    韩宝亿阅读 7,814评论 0 3

友情链接更多精彩内容