//拦截器class InterceptorsManage{  constructor(){    this.handlers=[];  }  use(resolve,reject){    this.handlers.push({      resolve,      reject    })  }}//勾销申请class CancelToken{  constructor(exactor){    //将promise给cancel。避免多次重复cancel    let resolvePromise;//promise实例的resolve办法    this.promise=new Promise(resolve=>{      resolvePromise=resolve;    })    this.reason=undefined;    const cancel=message=>{      if(this.reason){return}      this.reason='cancel'+message;      resolvePromise(this.reason);//扭转this.promise为resolve状态    }    exactor(cancel)  }  throwIfRequested() {    if(this.reason) {        throw this.reason    }  }  source(){    let cancel;//等于下面的cancel,一个函数    const token=new CancelToken(function exactor(c){      cancel=c;    });    return {      token,      cancel    }  }}class Axios{  constructor(){    this.interceptors={      request:new InterceptorsManage,      response:new InterceptorsManage    }  }  request(config){    //拦截器和申请组装队列    let chain=[this.sendAjax.bind(this),undefined];//成对呈现,一个胜利一个失败,失败回调暂不解决    //申请拦挡,调用request申请时,申请拦挡在前,响应拦挡在后    this.interceptors.request.handlers.forEach(inter=>{      chain.unshift(inter.resolve,inter.reject)    })    this.interceptors.response.handlers.forEach(inter=>{      chain.push(inter.resolve,inter.reject)    })    //执行队列,每次执行一对,并给promise最新的值    let promise=Promise.resolve(config);    while(chain.length>0){      //promise状态是resolved会执行then中第一个回调,1.request.use(胜利,失败),2.胜利把resolve(config)胜利后果给到sendAjax参数执行,3.sendAjax执行胜利,把后果response给response.use(胜利)参数执行      promise=promise.then(chain.shift(),chain.shift())    }    return promise;  }  sendAjax(config){    return new Promise(resolve=>{      const {url='',method='get',data={}}=config;      //发送申请      const xhr=new XMLHttpRequest();      xhr.open(method,url,true);      xhr.onreadystatechange=()=>{        if (xhr.status >= 200 && xhr.status <= 300 && xhr.readyState === 4) {          resolve(xhr.responseText)        } else {          reject('失败了')        }      };      if(config.cancelToken){        //promise为resolve状态时,勾销申请        config.cancelToken.promise.then(function onCancel(reason){//onCancel就是下面的resolvePromise          if(!xhr){return}          xhr.abort();//勾销申请          reject(reason)          xhr=null;        })      }      xhr.send(data)    })  }};//定义get,post等办法,挂到Axios上const methodsArr=['get','delete','head','options','put','patch','post'];methodsArr.forEach(met=>{  Axios.prototype[met]=function(){    console.log('执行'+met+'办法');    //解决单个办法,带2个参数(url,config)    if(['get','delete','head','options'].includes(met)){      return this.request({        method:met,        url:arguments[0],        ...arguments[1]||{}      })    }else{//3个参数(url,data,config),put,post有data      return this.request({        method:met,        url:arguments[0],        data:arguments[1]||{},        ...arguments[2]||{}      })    }  }});//继承类的办法及属性function extend(to,from,ctx){  for(let key in from){    //继承本身属性,不继承原型链,用hasOwnProperty判断    if(from.hasOwnProperty(key)){      if(typeof from[key]==='function'){        to[key]=from[key].bind(ctx)      }else{        to[key]=from[key]      }    }  }  return to;};//援用function createInstance(){  let context=new Axios();  //用实例化的context对象去接替Axios类的的request办法,反对axios({...})办法  let instance=Axios.prototype.request.bind(context);  //继承get,post,put等办法  extend(instance,Axios.prototype,context);  extend(instance,context)  return instance;}let axios=createInstance();//加拦截器axios.interceptors.request.use(function(config){  //发送之前做什么  return config;},function(err){  //申请出错  return Promise.reject(error)});axios.interceptors.response.use(function(response){  //响应数据做什么  return response;},function(err){  return Promise.reject(err)})//勾销申请// const {token,cancel}=cancelToken.source();// config.cancelToken=token;// setTimeout(()=>cancel,500)