axios
是結(jié)合promise
一起使用的译红,其中重要的一點是使用了promise.resolve()
和對應(yīng)的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,
});
}
};
//執(zhí)行axios方法
axios({
error: "",
result: 'jack',
}).then(res => {
console.log('res= ', res);
}).catch(err => {
console.log('err=> ', err);
});
當執(zhí)行上面的axios方法的時候嘉抓,會隨著傳入?yún)?shù)的判斷處理炕倘,執(zhí)行對應(yīng)的then里面的函數(shù)回調(diào)方法烛芬,從而達到異步數(shù)據(jù)流的控制读规。
攔截器實現(xiàn)思路:
我們可以通過設(shè)置一個操作鏈按声,存儲請求攔截操作、響應(yīng)攔截操作终蒂,通過promise的異步流達到依次順序執(zhí)行的目的蜂林。
//自定義axios
const axios = {
config: {
url: '/',
method: 'get',
baseURL: "",
params: {},
}
};
//存儲請求遥诉、響應(yīng)攔截操作函數(shù)
axios.interceptors = {
request: [],
response: [],
};
//調(diào)用攔截器的時候,將攔截操作方法加入攔截器操作鏈
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網(wǎng)絡(luò)請求的核心操作
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執(zhí)行噪叙,調(diào)用攔截器處理
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);
};
//導(dǎo)出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);
});
//響應(yīng)攔截器 中間件
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);
});
使用多個請求響應(yīng)攔截器的時候矮锈,要注意攔截器寫入的先后順序,當在攔截器中對config做攔截操作處理時睁蕾,會有對接下來的攔截器中config的操作有影響苞笨。如上請求,攔截器的執(zhí)行順序是:
interceptors.request2
interceptors.request1
ajax請求 http://localhost:9000/getData
interceptors.response1
interceptors.response2