1.创建构造函数
原始构造函数用于存储默认属性与拦截器操作
拦截器管理器构造函数InterceptorManager 主要是为了存储拦截器的失败与成功操作函数
- function Axios(config) {
- // 数据初始化
- this.defaults = config // 默认属性
- this.intercepters = { // 拦截器操作
- request: new InterceptorManager(), // 用于请求前拦截
- response: new InterceptorManager(), // 用于响应结果拦截
- }
- }
2.创建Axios构造函数的原型方法(get,post,request)
重点是request函数,主要是用promise来进行链式操作
创造promise
chain存储axios请求函数dispatchRequest,undefined(失败占位符)
请求拦截在头部插入
响应拦截在尾部插入
真实axios请求在(请求拦截)与(响应拦截)之间
先执行请求拦截再执行真是axios请求,最后执行响应拦截
while 保证全部执行
- // 创建原型方法
-
- Axios.prototype.get = function (config) {
- return this.request({ ...config, method: 'GET', })
- }
-
- Axios.prototype.post = function (config) {
- return this.request({ ...config, method: 'POST' })
- }
-
- Axios.prototype.request = function (config) {
- console.log('发送 AJAX 请求 请求的类型为 ' + config.method);
-
- // 发送请求
- // 创建promise对象
- let promise = Promise.resolve(config);
- //发送请求
- let chain = [dispatchRequest, undefined];//undefined进行占位
- // 请求拦截
- this.intercepters.request.handlers.forEach(item => {
- //头部插入,后写入的先执行
- chain.unshift(item.fulfilled, item.injected)
- })
- // debugger
- //响应拦截器
- this.intercepters.response.handlers.forEach(item => {
- //尾部插入,后写入的后执行
- chain.push(item.fulfilled, item.rejected);
- });
- //遍历
- while (chain.length > 0) {
- //保证全部执行,成功函数,失败函数
- promise = promise.then(chain.shift(), chain.shift());
- }
- return promise;
- }
3.创建dispatchRequest 函数
- function dispatchRequest(config) {
- return xhrRequest(config).then(response => {
- //响应的结果进行转换处理
- //....
- return response;
- }, error => {
- throw error;
- });
- }
4. xhrRequest发送请求
promise进行xhr请求
当存在cancelToken的时候进行取消操作
promise.then的执行时机是在cancel方法改变promise状态才执行
- function xhrRequest(config) {
- return new Promise((reslove, inject) => {
- let xhr = new XMLHttpRequest();
- xhr.open(config.method, config.url)
- xhr.send();
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
- if (xhr.status == 200 && xhr.status < 300) {
- reslove({
- config: config,
- data: xhr.response,
- Headers: xhr.getAllResponseHeaders(),
- request: xhr,
- status: xhr.status,
- statusText: xhr.statusText
- })
-
- } else {
- inject(new Error('请求失败 失败的状态码为' + xhr.status))
- }
- }
- }
- //关于取消请求的处理
- if (config.cancelToken) {
- //对 cancelToken 对象身上的 promise 对象指定成功的回调
- config.cancelToken.promise.then(value => {
- xhr.abort();
- console.log('请求已经被取消')
- //将整体结果设置为失败
- inject(new Error('请求已经被取消'))
- });
- }
- })
- }
6.拦截器管理器构造函数
- function InterceptorManager() {
- this.handlers = [];
- }
- InterceptorManager.prototype.use = function (fulfilled, rejected) {
- this.handlers.push({
- fulfilled,
- rejected
- })
- }
7.创建axios声明函数,生成axios,并将Axios的原型方法跟默认属性添加到axios上
- function createInstance(config) {
-
- // 实例化一个对象 , bind绑定this而不执行
- let context = new Axios(config)
- let instance = Axios.prototype.request.bind(context);
- // console.log(instance)
- // 将context的原型方法添加到instance上
- Object.keys(Axios.prototype).forEach(key => {
- instance[key] = Axios.prototype[key].bind(context)
-
- })
- // 将context中的default 与intercepters添加到instance上
- Object.keys(context).forEach(key => {
- instance[key] = context[key]
- })
-
- // console.dir(instance)
- return instance;
- }
8.绑定拦截器事件
- axios.intercepters.request.use(function one(config) {
- console.log('请求拦截器 成功 - 1号');
- return config;
- }, function one(error) {
- console.log('请求拦截器 失败 - 1号');
- return Promise.reject(error);
- });
-
- axios.intercepters.request.use(function two(config) {
- console.log('请求拦截器 成功 - 2号');
- return config;
- }, function two(error) {
- console.log('请求拦截器 失败 - 2号');
- return Promise.reject(error);
- });
-
- // 设置响应拦截器
- axios.intercepters.response.use(function (response) {
- console.log('响应拦截器 成功 1号');
- return response;
- }, function (error) {
- console.log('响应拦截器 失败 1号')
- return Promise.reject(error);
- });
-
- axios.intercepters.response.use(function (response) {
- console.log('响应拦截器 成功 2号')
- return response;
- }, function (error) {
- console.log('响应拦截器 失败 2号')
- return Promise.reject(error);
- });
9. CancelToken 构造函数用来取消请求
创造promise,先不执行resolve成功函数,而是将resolve存储起来,将function(){resolvePromise();}作为参数传递给cancel
- function CancelToken(executor){
- //声明一个变量
- var resolvePromise;
- //为实例对象添加属性
- this.promise = new Promise((resolve) => {
- //将 resolve 赋值给 resolvePromise
- resolvePromise = resolve
- });
- console.log(this.promise,'this.promise')
- //调用 executor 函数
- executor(function(){
- //执行 resolvePromise 函数
- resolvePromise();
- });
- }
使用
- "en">
-
- <head>
-
- "UTF-8">
- "viewport" content="width=device-width, initial-scale=1">
- <link href="css/style.css" rel="stylesheet">
-
- "container">
-
"page-header">axios取消请求
-
-
-
-
-
- this.resolvePromise1 =''
- let a=new Promise((resolve) => {
- //将 resolve 赋值给 resolvePromise
- resolvePromise1 = resolve
- })
-
-
- a.then(v=>{
- console.log(22222222222)
- })
-
- setTimeout(()=>{
- resolvePromise1()
- },2000)
- const btns = document.querySelectorAll('button');
- //2.声明全局变量
- let cancel = null;
- //发送请求
- btns[0].onclick = function () {
- //检测上一次的请求是否已经完成
- if (cancel !== null) {
- //取消上一次的请求
- cancel();
- }
-
- //创建 cancelToken 的值
- let cancelToken = new CancelToken(function (c) {
- console.log(c,'c')
- cancel = c;
- });
- debugger
- axios({
- method: 'GET',
- url: 'http://localhost:4000/products1',
- cancelToken: cancelToken
- }).then(response => {
- console.log(response);
- });
- }
- //绑定第二个事件取消请求
- btns[1].onclick = function () {
- cancel();
- }
-
-