axios
是结合promise
一起使用的,其中重要的一点是使用了promise.resolve()
和对应的promise.then()
;
先来看一个例子:
const axios = (config) => {
console.log(config);
if (config.error) {
return Promise.reject({
error: "error in axios"
});
} else {
return Promise.resolve({
...config,
result: config.result,
});
}
};
//执行axios方法
axios({
error: "",
result: 'jack',
}).then(res => {
console.log('res= ', res);
}).catch(err => {
console.log('err=> ', err);
});
当执行上面的axios方法的时候,会随着传入参数的判断处理,执行对应的then里面的函数回调方法,从而达到异步数据流的控制。
拦截器实现思路:
我们可以通过设置一个操作链,存储请求拦截操作、响应拦截操作,通过promise的异步流达到依次顺序执行的目的。
//自定义axios
const axios = {
config: {
url: '/',
method: 'get',
baseURL: "",
params: {},
}
};
//存储请求、响应拦截操作函数
axios.interceptors = {
request: [],
response: [],
};
//调用拦截器的时候,将拦截操作方法加入拦截器操作链
axios.interceptors.request.use = (resolved, rejected) => {
axios.interceptors.request.push({ resolved, rejected });
};
axios.interceptors.response.use = (resolved, rejected) => {
axios.interceptors.response.push({ resolved, rejected });
};
//axios网络请求的核心操作
axios.action = (config) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(config.method, config.baseURL + config.url, true);
xhr.onload = () => {
// console.log(xhr.status);
// console.log(xhr.responseText);
resolve(xhr.responseText);
};
xhr.onerror = () => {
//console.log('======== xhr.error');
reject('xhr error 错误');
};
xhr.send();
});
};
//axios执行,调用拦截器处理
axios.run = (config) => {
//console.log('config --- ', config);
const chain = [
{
resolved: axios.action,
rejected: undefined
}
];
axios.interceptors.request.forEach(interceptor => {
chain.unshift(interceptor);
});
axios.interceptors.response.forEach(interceptor => {
chain.push(interceptor);
});
let promise = Promise.resolve(config);
while (chain.length) {
const { resolved, rejected } = chain.shift();
promise = promise.then(resolved, rejected);
}
return promise;
};
//get请求
axios.get = (url) => {
axios.config.method = 'get';
axios.config.url = url;
return axios.run(axios.config);
};
//post请求
axios.post = (url) => {
axios.config.method = 'post';
axios.config.url = url;
return axios.run(axios.config);
};
//导出axios
export default axios;
自定义axios的使用:
import axios from './myAxios.js';
const getBtn = document.querySelector('#get');
const postBtn = document.querySelector('#post');
//axios的请求配置
axios.config.baseURL = "http://localhost:9000";
//get请求
getBtn.onclick = (e)=>{
//console.log('eee, ', e.target);
axios.get("/getData").then(res=>{
console.log('get request result = ', res);
alert(res);
}).catch(err=>{
alert('post err -> ', err);
});
};
//post请求
postBtn.onclick = (e)=>{
//console.log('eee, ', e.target);
axios.post("/postData").then(res=>{
console.log('get request result = ', res);
alert(res);
}).catch(err=>{
alert('post err -> ', err);
});
};
//请求拦截器 中间件
axios.interceptors.request.use((config) => {
console.log('interceptors.request1');
return config;
}, (error) => {
return Promise.reject(error);
});
axios.interceptors.request.use((config) => {
console.log('interceptors.request2');
return config;
}, (error) => {
return Promise.reject(error);
});
//响应拦截器 中间件
axios.interceptors.response.use((res) => {
console.log('interceptors.response1');
return res;
}, (error) => {
return Promise.reject(error);
});
axios.interceptors.response.use((res) => {
console.log('interceptors.response2');
return res;
}, (error) => {
return Promise.reject(error);
});
使用多个请求响应拦截器的时候,要注意拦截器写入的先后顺序,当在拦截器中对config做拦截操作处理时,会有对接下来的拦截器中config的操作有影响。如上请求,拦截器的执行顺序是:
interceptors.request2
interceptors.request1
ajax请求 http://localhost:9000/getData
interceptors.response1
interceptors.response2
网友评论