----欢迎查看个人博客----javascript
咱们以前,过分过来都在用ajax,那么什么是 Fetch ,Fetch 是新的游览器对象, 等同于 XMLHttpRequest对象 。它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性。html
废话很少说咱们来看一下传统的ajax。java
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
if (xhr) {
xhr.onreadystatechange = () =>{
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText); //返回值传callback
} else {
//failcallback
console.log('There was a problem with the request.');
}
} else {
console.log('still not ready...');
}
};
xhr.open('POST', 'https://www.baidu.com', true);
// 设置 Content-Type 为 application/x-www-form-urlencoded
// 以表单的形式传递数据
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('username=admin&password=root');
}
复制代码
好咱们来作层封装,让他变成咱们 jQuery 的 ajax post 如这种形式:ios
$.ajax({
method: 'POST', //请求方式
url: '/api', //url
data: { username: 'admin', password: 'root' }, //值
success:function(data){ //成功回掉
console.log(data)
},
error:function(err){
console.log(err)
}
})
复制代码
好的封装开始:ajax
const $ = {};
$.ajax = (obj)=>{
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
if (xhr) {
xhr.onreadystatechange = () =>{
if (xhr.readyState === 4) {
if (xhr.status === 200) {
obj.success(xhr.responseText); //返回值传callback
} else {
//failcallback
obj.error('There was a problem with the request.');
}
} else {
console.log('still not ready...');
}
};
xhr.open(obj.method, obj.url, true);
// 设置 Content-Type 为 application/x-www-form-urlencoded
// 以表单的形式传递数据
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(util(obj.data));//处理body数据
}
//处理数据
const util = (obj)=>{
var str = ''
for (key in obj){
str += key +'='+obj[key]+'&'
}
return str.substring(0,str.length-1)
}
}
复制代码
ok,我们已经封装完毕,可使用了,但是你会发现,这种书写方式很混乱,body,hearder乱七八糟,还有回掉地狱的问题。好的fetch出来了。json
咱们说了,一种东西的诞生有它的道理,他首先解决了回掉地狱的问题由于返回一个 promise 对象 ,对 promise 对象不是很熟悉的同窗能够看这篇文章: 你就须要这篇文章,带你搞懂实战的 Promise 对象。一样既然是 promise 对象咱们就可使用 es7 的 async / await 戳这里。好了废话很少说咱们看看最基础的 fetch 怎么写吧 。axios
fetch(url, options).then(function(response) {
// handle HTTP response
}, function(error) {
// handle network error
})
复制代码
就是这么方便,就是这么简单。 fetch 会先发起一个 option 的请求,肯定是否链接成功,而后再发送正式的请求 ,就比如 xhr.readyState === 4 这个一个道理。那有同窗就问了,个人逻辑比较复杂 。个人 fetch 要加请求头,参数我要传参传 formData 不是 json。 咱们来看fetch发送formdata:api
fetch(url,{
method:"post",
headers:{
"Content-type":"application:/x-www-form-urlencoded:charset=UTF-8"
},
body:"name=admin&password=123456"
}).then(function(response){
if(response.ok){
response.json().then(json => {
console.log(json.result)
})
}
}).catch(function(err){
console.log("Fetch错误:"+err);
});
复制代码
发送json格式也很是简单。promise
fetch(url,{
method:"post",
headers:{
'Content-Type':'application/json; charset=UTF-8'
},
body:JSON.stringify({name:'admin',password:123456})
}).then(function(response){
if(response.ok){
response.json().then(json => {
console.log(json.result)
})
}
}).catch(function(err){
console.log("Fetch错误:"+err);
});
复制代码
浏览器已经开始为 AbortController 和 AbortSignal 接口(也就是Abort API)添加实验性支持,容许像 Fetch 和 XHR 这样的操做在还未完成时被停止 。请参阅接口页面了解更多详情。可是目前对游览器的支持并不很好,因此咱们其实能够换一种思路, 取消 fetch 咱们能够从另一个面入手 ---- 能够取消 promise 。原生的固然不行了,因此咱们这里用到了 bluebird。浏览器
//传统 promise
var promises = [];
for (var i = 0; i < fileNames.length; ++i) {
promises.push(fs.readFileAsync(fileNames[i]));
}
Promise.all(promises).then(function() {
console.log("done");
});
// Using Promise.map:
import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
// Promise.map awaits for returned promises as well.
return fs.readFileAsync(fileName);
}).then(function() {
console.log("done");
});
复制代码
import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
// Promise.map awaits for returned promises as well.
return fs.readFileAsync(fileName).then(()=>{
//若是flag = true 就中断。
if (flag){
throw new Error('中断')
}
});;
}).then(function() {
console.log("done");
}).catch(function (err) {
console.log('Error', err.message)
});
复制代码
若是取消单个 promise 能够用 .cancel 方法,具体看 bluebird 文档。
从文档中咱们能够看出为何这个会火 ,axios 他的功能很是强大,包括 取消请求 ,进度处理等等。可是咱们看的是本质仍是 ajax ,在基础上进行了封装和功能的添加
XMLHttpRequests 支持 Promise
//一个post请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
复制代码
其实咱们看出来, ajax 和 Axios 在客户端都是调用 XMLHttpRequests 对象 ,而咱们的 fetch 是一个新的游览器对象 。只不过 ajax 和 Axios 区别就是在 封装了简便的方法,而且提供了一个 promise 对象。