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. 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',()=>{});
网友评论