Fetch 的出现就是为了解决 XMLHttpRequest(简称XHR) 的问题
使用 XHR 发送一个 json 请求一般是这样:
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function() {
console.log(xhr.response);
};
xhr.onerror = function() {
console.log("Oops, error");
};
xhr.send();
使用 Fetch 后,顿时看起来好一点
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
使用 ES6 的 arrow function 后
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
使用 async/await 来做最终优化:
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
// 注:这段代码如果想运行,外面需要包一个 async function
使用 await 后, 写异步代码就像写同步代码一样爽 。 await 后面可以跟 Promise 对象,
表示等待 Promise resolve() 才继续执行,如果 Promise 被 reject() 或抛出异常则会被
外面的 try...catch 捕获。
Fetch 常见坑
Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: 'include'})
服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,
fetch 才会被 reject。
IE 使用策略
所有版本的 IE 均不支持 Fetch,fetch-ie8 会自动使用 XHR 做 polyfill。
但在跨域时有个问题需要处理。
IE8, 9 的 XHR 不支持 CORS 跨域,虽然提供 XDomainRequest ,但这个东西就是玩具,
不支持传 Cookie!如果接口需要权限验证,还是乖乖地使用 jsonp 吧,推荐使用 fetch-jsonp 。
如果有问题直接提 issue,我会第一时间解决。
标准 Promise 的不足:
由于 Fetch 是典型的异步场景,所以大部分遇到的问题不是 Fetch 的,其实是 Promise 的。
ES6 的 Promise 是基于 Promises/A+ 标准,为了保持 简单简洁 ,只提供极简的几个 API。
如果你用过一些牛 X 的异步库,如 jQuery(不要笑) 、Q.js 或者 RSVP.js,
可能会感觉 Promise 功能太少了。
没有 Deferred:
Deferred 可以在创建 Promise 时可以减少一层嵌套,跨方法使用时很方便。
ECMAScript 11 年就有过 Deferred 提案 ,但后来没被接受。其实用 Promise
不到十行代码就能实现 Deferred: es6-deferred 。
现在有了 async/await,generator/yield 后,deferred 就没有使用价值了。