1. 基于callback的XMLHttpRequest处理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. 基于promise的fetch处理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返回一个value为response object的resolved promise; -
response object调用Body.json()函数,返回一个新的promise,这个promise被resolve之后,返回的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, value为undefined, 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',()=>{});










网友评论